PLSQL重点问题理解和实战
一 ORACLE中PL/SQL使用的集合變量類型有RECORD(類)、VARRAY(sql數組)、TABLE(嵌套表)
TABLE(嵌套表) 可以加index定義也可以不加,加表示index by是建立主鍵索引相當于數組,不加就是個嵌套表集合
1 TABLE(嵌套表)定義表變量類型
? type type_table_emp_empno is table of emp.empno%type index by binary_integer;--TYPE表示表中一行中字段類型
? v_empnos type_table_emp_empno;
? 如果用%type定義
? 定義集合變量v_empnos 是一個有emp.empno字段類型的數組,自己理解是存放實際還是一個表,里面只有一個字段,且字段上有索引
? 對此集合變量(is table of index by)類型的操作 包括count,delete,但不能用trim
? 對VARRAY 可以用count,delete和trim
? 使用形式
? select to_char(truck_in_out_id),
??????? employee_id,
??????? employee_nm,
??????? truck_in_purpose
?? bulk collect into
??????? carid,
??????? empid,
??????? empnm,
??????? dest
?
?? forall i in 1 .. carid.COUNT
?
?? update cpnew.CP_VISIT_APPLY? a
????? set a.mgr_principal_id = empid(i),
????????? a.mgr_principal_nm = empnm(i),
????????? a.visit_dest?????? = dest(i)
??? where a.visit_apply_id = carid(i)
????? and a.mgr_principal_id is null;
??
? type delArray1 is table of TEST.COURSE%ROWTYPE index by binary_integer; --ROWTYPE表示表中一行的記錄類型
? cur_result delArray1;
? 如果用%rowtype定義
? 定義集合變量cur_result是一個COURSE表類型的集合,自己理解是按一個表存放,里面包括COURSE的所有字段類型,且用整形數做這個表的索引
? 使用形式
? select * bulk collect into cur_result
?
?? forall i in 1 .. cur_result.COUNT
?
?? update cpnew.CP_VISIT_APPLY? a
????? set a.mgr_principal_id = cur_result(i).empid,
????????? a.mgr_principal_nm = cur_result(i).empnm,
????????? a.visit_dest?????? = cur_result(i).dest
??? where a.visit_apply_id = cur_result(i).carid
????? and a.mgr_principal_id is null;
?
?
實際工作中的例子
plsql 大數據量刪除,修改的方法FORALL加bulk collection into
create or replace procedure zl_del_UPDATEAPPLY_DEST187 as
? --type ridArray is table of rowid index by binary_integer;
? type delArray1 is table of varchar2(32) index by binary_integer;
? type delArray2 is table of CP_2012.CP_VISIT_TRUCK_INOUT.employee_id%type index by binary_integer;
? type delArray3 is table of CP_2012.CP_VISIT_TRUCK_INOUT.employee_nm%type index by binary_integer;
? type delArray4 is table of CP_2012.CP_VISIT_TRUCK_INOUT.truck_in_purpose%type index by binary_integer;
? //你會發現用%type就得每個字段都得定義他的類型
? carid delArray1;
? empid delArray2;
? empnm delArray3;
? dest delArray4;
begin
?
?? select to_char(truck_in_out_id),
??????? employee_id,
??????? employee_nm,
??????? truck_in_purpose
?? bulk collect into
??????? carid,
??????? empid,
??????? empnm,
??????? dest
?? from CP_2012.CP_VISIT_TRUCK_INOUT;
?? --where rownum < 600001;
?
? forall i in 1 .. carid.COUNT
?
?? update cpnew.CP_VISIT_APPLY? a
????? set a.mgr_principal_id = empid(i),
????????? a.mgr_principal_nm = empnm(i),
????????? a.visit_dest?????? = dest(i)
??? where a.visit_apply_id = carid(i)
????? and a.mgr_principal_id is null;
? DBMS_OUTPUT.PUT_LINE(to_char(carid.COUNT) ||
?????????????????????? ' records deleted from temp_mid_hubei_bak?? !!!');????????????????
??
end;
這種方法最大缺點是forall里不能訪問遠程表,也不能用dblink,且只能放dml語句不能用dbms.putline
經過測試過發現for可以替代forall盡管時間相對慢一點,但也能接受,所以可以在for中用dblink,相應語句如下:
for i in 1 .. carid.COUNT
? loop
???? update cpnew.CP_VISIT_APPLY@LINK_213TO187_CPNEW? a
????? set a.mgr_principal_id = empid(i),
????????? a.mgr_principal_nm = empnm(i),
????????? a.visit_dest?????? = dest(i)
???? where a.visit_apply_id = carid(i)
????? and a.mgr_principal_id is null;
2 Record變量類型:(相當于java的類)
定義
type type_record_dept is record
??????? (
??????????? deptno dept.deptno%type,
??????????? dname dept.dname%type,
??????????? loc dept.loc%type
??????? );
??? v_temp type_record_dept;
3 VARRAY
定義和使用
CREATE OR REPLACE TYPE numbers_t IS VARRAY (5) OF NUMBER
DECLARE
?? l_list numbers_t:= numbers_t (1, 2, 3, 4, 5);
BEGIN
?? l_list.DELETE;
?? DBMS_OUTPUT.put_line (CASE l_list.COUNT WHEN 0 THEN 'Empty' END);
END;
數組使用例子 參考 Oracle數組的使用 http://blog.itpub.net/12932950/viewspace-351791/
還可以對比本人之前的blog查看游標和bulk collect into的用法 http://blog.itpub.net/750077/viewspace-2075986/
二 PL/SQL異常
異常類型 1預定義的異常處理,2非預定義 ( Predefined )錯誤,3用戶定義(User_define) 錯誤
一般預定義和用戶定義異常使用較多
1預定義異常 如oracle已定義的異常
ORA-1403 No_data_found SELECT INTO沒有找到數據
使用時如果select沒查出數據時就直接處理沒找到數據的異常
EXCEPTION
?WHEN NO_DATA_FOUND THEN?
????? DBMS_OUTPUT.PUT_LINE('數據庫中沒有編碼為'||v_empno||'的員工');
END;
2用戶自定義異常
用戶先定義異常
no_result? EXCEPTION;
如沒有更新的數據時,拋出這個異常
UPDATE employees SET salary = salary+100 WHERE employee_id = v_empno;
?? IF SQL%NOTFOUND THEN
????? RAISE no_result;
?? END IF;
然后處理這個異常
EXCEPTION
?? WHEN no_result THEN
????? DBMS_OUTPUT.PUT_LINE('你的數據更新語句失敗了!');
?? WHEN OTHERS THEN
????? DBMS_OUTPUT.PUT_LINE(SQLCODE||'---'||SQLERRM);
END;
SQLCODE,SQLERRM是ORACLE函數,會打印錯誤代碼和錯誤名稱
參考 ORACLE PL/SQL編程之五:異常錯誤處理 https://www.cnblogs.com/huyong/archive/2011/05/06/2038743.html
后續持續更新
......
總結
以上是生活随笔為你收集整理的PLSQL重点问题理解和实战的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【297天】我爱刷题系列056(2017
- 下一篇: 【js基础】理清Object、Objec