zoukankan      html  css  js  c++  java
  • 测试REF_CCURSOR和SYS_CURSOR的区别、自治事务Autonomous Transaction的使用、BULK COLLECTION INTO 和 FORALL语句的使用

    包头:

      1 CREATE OR REPLACE PACKAGE TEST_REF_CURSOR IS
    2
    3 -- AUTHOR : ADMINISTRATOR
    4 -- CREATED : 2011-12-28 10:57:32
    5 -- PURPOSE : 测试REF_CCURSOR和SYS_CURSOR的区别:自治事务Autonomous Transaction的使用:
    6 -- BULK COLLECTION INTO 和 FORALL语句的使用
    7
    8 /*
    9 O_RETURNFLAG:用于判断该存储过程是否成功执行,并在出错后存储相应的错误原因。
    10 如果它的值的第一位为S,则表明该存储过程成功执行,没有错误。
    11 如果它的值的第一位为E,则表明该存储过程执行失败,具体错误原因为它的值的第二位到最后一位。
    12 */
    13
    14 SUCCESS CONSTANT VARCHAR2(100) := 'SUCCESS';
    15 FAIL CONSTANT VARCHAR2(100) := 'FAIL';
    16
    17 /*
    18 *自治事务官方文档:http://docs.oracle.com/cd/B10501_01/appdev.920/a96624/06_ora.htm#1990
    19 *事务的隔离机制:http://epub.itpub.net/3/4.htm
    20 *Pragama的意思,自治事务的概念
    21 *Pragama is compile directive .
    22 *Example of Autonomous transactions
    23 *Suppose you are updating value from table and you don't have update trigger
    24 *on that table , but still you want to maintain a log entry for this update
    25 *in seprate table.
    26 *You can write a procedure and call that procedure to do this . But you can not
    27 *use COMMIT in this called procedure because it will save the entire transaction.
    28 *To avoid this you can delclare this procedure as autonomous transaction procedure
    29 *so that the execution of this procedure will be treated as totally diff. transaction and you can issue commit in called procedure without affecting the main transaction.
    30 */
    31
    32 /***************************************************************************
    33 *
    34 *以下为Pragama和自治事务Autonomous Transaction的使用:
    35 * Autonomous Transaction is a feature of oracle 8i which maintains the state
    36 *of its transactions and save it , to affect with the commit or rollback of
    37 *the surrounding transactions.
    38 *
    39 ****************************************************************************/
    40
    41 /***********************************************************
    42 *没有自制事务的例子
    43 ************************************************************/
    44 PROCEDURE TEST_NO_PRAGAMA;
    45
    46 /***********************************************************
    47 *没有自制事务的例子,测试上一个过程:
    48 *测试结果:The Rollback at line-no 11 actually did nothing.
    49 *Commit/ROLLBACK at nested transactions will commit/rollback
    50 *all other DML transaction before that. PRAGMA AUTONOMOUS_TRANSACTION
    51 *override this behavior.
    52 ************************************************************/
    53 PROCEDURE TEST_NO_PRAGAMA_RUN;
    54
    55 /***********************************************************
    56 *使用自治事务的例子
    57 ************************************************************/
    58 PROCEDURE TEST_WITH_PRAGAMA;
    59
    60 /***********************************************************
    61 *没有自制事务的例子,测试上一个过程:
    62 *测试结果:The Rollback at line-no 11 actually did nothing.
    63 *Commit/ROLLBACK at nested transactions will commit/rollback
    64 *all other DML transaction before that. PRAGMA AUTONOMOUS_TRANSACTION
    65 *override this behavior.
    66 ************************************************************/
    67 PROCEDURE TEST_WITH_PRAGAMA_RUN;
    68
    69 /***************************************************************************
    70 *
    71 *
    72 *以下为游标的使用:主要是测试REF CURSOR和SYS_REFCURSOR
    73 *
    74 ****************************************************************************/
    75
    76 --声明一个REF CURSOR并且具有返回值,当使用RETURN的时候,
    77 --RETURN的类型必须是记录类型
    78 --TYPE RETURN_CUR IS REF CURSOR RETURN EMP%ROWTYPE;
    79
    80 --声明一个普通的REF CURSOR
    81 TYPE RETURN_CUR IS REF CURSOR;
    82
    83 --定义输出的类型为REF CURSOR的过程
    84 PROCEDURE CHILD(P_CURSOR OUT RETURN_CUR);
    85
    86 --调用过程CHILD,进行输出参数的接收
    87 PROCEDURE PARENTS(P_IN_SIZE PLS_INTEGER);
    88
    89 --定义输出的类型为SYS_REFCURSOR的过程
    90 PROCEDURE CHILD_SYS(P_CURSOR OUT SYS_REFCURSOR);
    91
    92 --调用过程CHILD_SYS,进行输出参数的接收
    93 PROCEDURE PARENTS_SYS(P_IN_SIZE PLS_INTEGER);
    94
    95 --传递一个游标,并进行批量处理
    96 PROCEDURE PARSE_CURSOR(P_CURSOR IN SYS_REFCURSOR);
    97
    98 --测试PARSE_CURSOR过程
    99 PROCEDURE TEST_PARSE_CURSOR;
    100
    101 /***************************************************************************
    102 *
    103 *以下为BULK COLLECTION INTO 和 FORALL语句的使用
    104 *BULK COLLECTION:批量插入的结合中:
    105 *FORALL是对结果进行批量的处理,主要是包括INERT、UPDATE、DELETE
    106 *
    107 ****************************************************************************/
    108
    109 /***************************************************************************
    110 *
    111 *BULK COLLECT的语法使用:
    112 * FETCH BULK COLLECT <CURSOR_NAME> BULK COLLECT INTO <COLLECTION_NAME>
    113 * LIMIT <NUMERIC_EXPRESSION>;
    114 * OR
    115 * FETCH BULK COLLECT <CURSOR_NAME> BULK COLLECT INTO <ARRAY_NAME>
    116 * LIMIT <NUMERIC_EXPRESSION>;
    117 *FORALL语法的使用:
    118 *FORALL <INDEX_NAME> IN <LOWER_BOUNDARY> .. <UPPER_BOUNDARY>
    119 * <SQL_STATEMENT>
    120 * SAVE EXCEPTIONS;
    121 *
    122 * FORALL <INDEX_NAME> IN INDICES OF <COLLECTION>
    123 * [BETWEEN <LOWER_BOUNDARY> AND <UPPER_BOUNDARY>]
    124 * <SQL_STATEMENT>
    125 * SAVE EXCEPTIONS;
    126 *
    127 * FORALL <INDEX_NAME> IN INDICES OF <COLLECTION>
    128 * VALUES OF <INDEX_COLLECTION>
    129 * <SQL_STATEMENT>
    130 * SAVE EXCEPTIONS;
    131 *
    132 ****************************************************************************/
    133 TYPE A IS TABLE OF VARCHAR2(100);
    134
    135 --测试1:未使用LIMIT参数(BULK COLLECT)
    136 PROCEDURE TEST_BULK_COOLECT_1(O_RETURN_FLAG OUT VARCHAR2);
    137
    138 --测试2:使用LIMIT参数(BULK COLLECT)
    139 PROCEDURE TEST_BULK_COOLECT_2(P_LIMIT PLS_INTEGER,
    140 O_RETURN_FLAG OUT VARCHAR2);
    141
    142 --测试FORALL的简单使用(INSERT/DELETE/UPDATE)
    143 PROCEDURE TEST_FORALL(O_RETURN_FLAG OUT VARCHAR2);
    144
    145 --测试FORALL的使用:
    146 PROCEDURE TEST_FORALL_BULK_OP(P_LIMIT PLS_INTEGER,
    147 O_RETURN_FLAG OUT VARCHAR2);
    148
    149 --测试FORALL的INDICES使用
    150 --INDICES:A SPARSE COLLECTION IS ONE FROM WHICH ELEMENTS HAVE BEEN DELETED.
    151 --INDICES表示插入的时候,排除之前删除的数据
    152 -- Since the subscripts of our collections are not consecutive,
    153 -- we use use FORRALL...INDICES OF to iterate the subscripts
    154 PROCEDURE TEST_INDICES(O_RETURN_FLAG OUT VARCHAR2);
    155
    156 --测试FORALL的VALUE的使用
    157 --使用INDICES和VALUE主要是处理不连续的下标的联合数组
    158 --PROCEDURE TEST_INDICES(O_RETURN_FLAG OUT VARCHAR2);
    159
    160 --FORALL操作的过程中的异常处理
    161 PROCEDURE TEST_EXCEPTION(O_RETURN_FLAG OUT VARCHAR2);
    162
    163 --快速插入数据(常用方法)
    164 PROCEDURE TEST_INSERT_GENERAL(O_RETURN_FLAG OUT VARCHAR2);
    165
    166 --快速插入数据1、使用VARRAY TABLE
    167 PROCEDURE TEST_INSERT_FAST1(O_RETURN_FLAG OUT VARCHAR2);
    168
    169 --快速插入数据2、使用联合数组
    170 PROCEDURE TEST_INSERT_FAST2(O_RETURN_FLAG OUT VARCHAR2);
    171
    172 --批量插入数据,一条一条的处理
    173 PROCEDURE TEST_BATCH_1(I_NAME IN VARCHAR2, O_RETURN_FLAG OUT VARCHAR2);
    174
    175 --批量插入数据,FORALL处理
    176 PROCEDURE TEST_BATCH_2(I_NAME IN VARCHAR2, O_RETURN_FLAG OUT VARCHAR2);
    177
    178 END TEST_REF_CURSOR;

    包体:

      1 CREATE OR REPLACE PACKAGE BODY TEST_REF_CURSOR IS
    2
    3 /***********************************************************
    4 *没有自制事务的例子
    5 ************************************************************/
    6 PROCEDURE TEST_NO_PRAGAMA IS
    7 BEGIN
    8
    9 INSERT INTO D (IDS) VALUES ('exist');
    10 COMMIT;
    11 END;
    12
    13 /***********************************************************
    14 *没有自制事务的例子,测试上一个过程
    15 *测试结果:The Rollback at line-no 11 actually did nothing.
    16 *Commit/ROLLBACK at nested transactions will commit/rollback
    17 *all other DML transaction before that. PRAGMA AUTONOMOUS_TRANSACTION
    18 *override this behavior.
    19 *两个表中同时出现数据
    20 ************************************************************/
    21 PROCEDURE TEST_NO_PRAGAMA_RUN IS
    22 BEGIN
    23
    24 INSERT INTO E (IDS) VALUES ('exist');
    25 TEST_NO_PRAGAMA;
    26 ROLLBACK;
    27 END;
    28
    29 /***********************************************************
    30 *使用自治事务的例子: PRAGMA AUTONOMOUS_TRANSACTION
    31 ************************************************************/
    32 PROCEDURE TEST_WITH_PRAGAMA IS
    33 --使用自治事务
    34 PRAGMA AUTONOMOUS_TRANSACTION;
    35 BEGIN
    36 INSERT INTO D (IDS) VALUES ('exist');
    37 COMMIT;
    38 END;
    39
    40 /***********************************************************
    41 *没有自制事务的例子,测试上一个过程:
    42 *测试结果:With PRAGMA AUTONOMOUS_TRANSACTION , the transaction
    43 *state maintained independently . Commit/Rollback of nested
    44 *transaction will no effect the other transaction. It is
    45 *advisable to increase the value of TRANSACTIONS parameter
    46 *in the INIT parameter file to allow for the extra concurrent
    47 *transaction
    48 ************************************************************/
    49 PROCEDURE TEST_WITH_PRAGAMA_RUN IS
    50 BEGIN
    51 INSERT INTO E (IDS) VALUES ('exist');
    52 TEST_WITH_PRAGAMA;
    53 ROLLBACK;
    54 END;
    55
    56 /***************************************************************************
    57 *
    58 *以下为游标的使用:主要是测试REF CURSOR和SYS_REFCURSOR
    59 *
    60 ****************************************************************************/
    61
    62 /***********************************************************
    63 *打开输出参数的游标(REF CURSOR)
    64 ************************************************************/
    65 PROCEDURE CHILD(P_CURSOR OUT RETURN_CUR) IS
    66 BEGIN
    67 OPEN P_CURSOR FOR
    68 SELECT ENAME FROM EMP;
    69 END;
    70
    71 PROCEDURE PARENTS(P_IN_SIZE PLS_INTEGER) IS
    72 V_RET_CUR RETURN_CUR;
    73 V_ENAME EMP.ENAME%TYPE;
    74 BEGIN
    75 --进行返回游标的处理,并打印结果
    76 CHILD(V_RET_CUR);
    77 FOR I IN 1 .. P_IN_SIZE LOOP
    78 FETCH V_RET_CUR
    79 INTO V_ENAME;
    80 DBMS_OUTPUT.PUT_LINE(V_ENAME);
    81 EXIT WHEN V_RET_CUR%NOTFOUND;
    82 END LOOP;
    83 NULL;
    84 END;
    85
    86 /***********************************************************
    87 *打开输出参数的游标(SYS_REFCURSOR)
    88 ************************************************************/
    89
    90 PROCEDURE CHILD_SYS(P_CURSOR OUT SYS_REFCURSOR) IS
    91 BEGIN
    92 OPEN P_CURSOR FOR
    93 SELECT ENAME FROM EMP;
    94 END;
    95
    96 PROCEDURE PARENTS_SYS(P_IN_SIZE PLS_INTEGER) IS
    97 V_SYS_REFCURSOR SYS_REFCURSOR;
    98 V_ENAME EMP.ENAME%TYPE;
    99 BEGIN
    100 --进行返回游标的处理,并打印结果
    101 CHILD_SYS(V_SYS_REFCURSOR);
    102 FOR I IN 1 .. P_IN_SIZE LOOP
    103 FETCH V_SYS_REFCURSOR
    104 INTO V_ENAME;
    105 DBMS_OUTPUT.PUT_LINE(V_ENAME);
    106 EXIT WHEN V_SYS_REFCURSOR%NOTFOUND;
    107 END LOOP;
    108 END;
    109
    110 /***********************************************************
    111 *传递一个游标,并进行批量处理
    112 ************************************************************/
    113
    114 PROCEDURE PARSE_CURSOR(P_CURSOR IN SYS_REFCURSOR) IS
    115 --定义联合表
    116 TYPE TYP_EMP_TAB IS TABLE OF VARCHAR2(4000) INDEX BY PLS_INTEGER;
    117 --定义变量
    118 TYP_EMP TYP_EMP_TAB;
    119 BEGIN
    120 --批量进行数据的处理:
    121 FETCH P_CURSOR BULK COLLECT
    122 INTO TYP_EMP;
    123
    124 DBMS_OUTPUT.PUT_LINE('使用基本LOOP循环');
    125 FOR I IN TYP_EMP.FIRST .. TYP_EMP.LAST LOOP
    126 DBMS_OUTPUT.PUT_LINE(TYP_EMP(I));
    127 END LOOP;
    128 END;
    129
    130 --测试PARSE_CURSOR过程
    131 PROCEDURE TEST_PARSE_CURSOR IS
    132 P_CURSOR SYS_REFCURSOR;
    133 BEGIN
    134 OPEN P_CURSOR FOR
    135 SELECT ENAME FROM EMP;
    136 PARSE_CURSOR(P_CURSOR);
    137 END;
    138
    139 /***************************************************************************
    140 *
    141 *
    142 *以下为BULK COLLECTION INTO 和 FORALL语句的使用
    143 *BULK COLLECTION:批量插入的结合中:
    144 *FORALL是对结果进行批量的处理,主要是包括INERT、UPDATE、DELETE
    145 *
    146 ****************************************************************************/
    147
    148 /***********************************************************
    149 *测试1:
    150 ************************************************************/
    151 PROCEDURE TEST_BULK_COOLECT_1(O_RETURN_FLAG OUT VARCHAR2) IS
    152 TYPE TYPE_TAB IS TABLE OF VARCHAR2(100);
    153 MY_TAB TYPE_TAB;
    154 CURSOR V_CURSOR IS
    155 SELECT OBJECT_ID FROM ALL_OBJECTS A;
    156 BEGIN
    157 O_RETURN_FLAG := 'S';
    158 --打开游标,批量插入
    159 OPEN V_CURSOR;
    160 LOOP
    161 FETCH V_CURSOR BULK COLLECT
    162 INTO MY_TAB;
    163 --DBMS_OUTPUT.PUT_LINE();
    164 EXIT WHEN V_CURSOR%NOTFOUND;
    165 END LOOP;
    166 CLOSE V_CURSOR;
    167 DBMS_OUTPUT.PUT_LINE(MY_TAB.COUNT);
    168 --循环嵌套表,插入数据
    169 FOR IDX IN MY_TAB.FIRST .. MY_TAB.LAST LOOP
    170 EXECUTE IMMEDIATE 'INSERT INTO D(IDS) VALUES(:1)'
    171 USING MY_TAB(IDX);
    172 END LOOP;
    173 COMMIT;
    174 --异常处理
    175 EXCEPTION
    176 WHEN OTHERS THEN
    177 O_RETURN_FLAG := 'E' || '_' || SQLCODE || '_' || SQLERRM;
    178 RETURN;
    179 END;
    180
    181 /***********************************************************
    182 *测试2:使用LIMIT参数
    183 ************************************************************/
    184 PROCEDURE TEST_BULK_COOLECT_2(P_LIMIT PLS_INTEGER,
    185 O_RETURN_FLAG OUT VARCHAR2) IS
    186 TYPE TYPE_TAB IS TABLE OF VARCHAR2(100);
    187 MY_TAB TYPE_TAB;
    188 CURSOR V_CURSOR IS
    189 SELECT OBJECT_ID FROM ALL_OBJECTS;
    190 BEGIN
    191 O_RETURN_FLAG := 'S';
    192 --判断输入的是否是数字
    193 DECLARE
    194 V_FLAG NUMBER;
    195 BEGIN
    196 V_FLAG := P_LIMIT / 1;
    197 IF V_FLAG <= 0 THEN
    198 O_RETURN_FLAG := 'E' || '请输入正整数';
    199 RETURN;
    200 END IF;
    201 EXCEPTION
    202 WHEN OTHERS THEN
    203 O_RETURN_FLAG := 'E' || '_' || SQLCODE || '_' || SQLERRM;
    204 ROLLBACK;
    205 RETURN;
    206 END;
    207
    208 --打开游标,批量插入
    209 OPEN V_CURSOR;
    210 LOOP
    211 FETCH V_CURSOR BULK COLLECT
    212 INTO MY_TAB LIMIT P_LIMIT;
    213
    214 --循环嵌套表,插入数据
    215 FOR IDX IN MY_TAB.FIRST .. MY_TAB.LAST LOOP
    216 EXECUTE IMMEDIATE 'INSERT INTO D(IDS) VALUES(:1)'
    217 USING MY_TAB(IDX);
    218 END LOOP;
    219 COMMIT;
    220
    221 EXIT WHEN V_CURSOR%NOTFOUND;
    222
    223 END LOOP;
    224 CLOSE V_CURSOR;
    225 DBMS_OUTPUT.PUT_LINE(MY_TAB.COUNT);
    226
    227 --异常处理
    228 EXCEPTION
    229 WHEN OTHERS THEN
    230 O_RETURN_FLAG := 'E' || '_' || SQLCODE || '_' || SQLERRM;
    231 ROLLBACK;
    232 RETURN;
    233 END;
    234
    235 /***********************************************************
    236 *测试FORALL的简单使用(INSERT/DELETE/UPDATE)
    237 ************************************************************/
    238 PROCEDURE TEST_FORALL(O_RETURN_FLAG OUT VARCHAR2) IS
    239 TYPE TYPE_TAB IS TABLE OF VARCHAR2(100) INDEX BY PLS_INTEGER;
    240 MY_TAB TYPE_TAB;
    241 BEGIN
    242 O_RETURN_FLAG := 'S';
    243 --初始化联合数组
    244 MY_TAB(1) := 'C';
    245 MY_TAB(2) := 'B';
    246 MY_TAB(3) := 'A';
    247
    248 --使用FORALL插入数据
    249 FORALL IDX IN MY_TAB.FIRST .. MY_TAB.LAST
    250 INSERT INTO D VALUES (MY_TAB(IDX));
    251 COMMIT;
    252
    253 --使用FORALL更新数据
    254 /* FORALL IDX IN MY_TAB.FIRST .. MY_TAB.LAST
    255 UPDATE D SET D.IDS = MY_TAB(IDX);
    256 COMMIT;*/
    257
    258 --使用FORALL删除数据
    259 /*FORALL IDX IN MY_TAB.FIRST .. MY_TAB.LAST
    260 DELETE FROM D WHERE D.IDS = MY_TAB(IDX);
    261 COMMIT;*/
    262
    263 EXCEPTION
    264 WHEN OTHERS THEN
    265 O_RETURN_FLAG := 'E' || '_' || SQLCODE || '_' || SQLERRM;
    266 ROLLBACK;
    267 RETURN;
    268 END;
    269
    270 /***********************************************************
    271 *测试FORALL的使用(INSERT):
    272 ************************************************************/
    273 PROCEDURE TEST_FORALL_BULK_OP(P_LIMIT PLS_INTEGER,
    274 O_RETURN_FLAG OUT VARCHAR2) IS
    275 TYPE TYPE_TAB IS TABLE OF VARCHAR2(100) INDEX BY PLS_INTEGER;
    276 MY_TAB TYPE_TAB;
    277 CURSOR V_CURSOR IS
    278 SELECT OBJECT_ID FROM ALL_OBJECTS A;
    279 BEGIN
    280 O_RETURN_FLAG := 'S';
    281 --打开游标,批量插入
    282 OPEN V_CURSOR;
    283 LOOP
    284 FETCH V_CURSOR BULK COLLECT
    285 INTO MY_TAB LIMIT P_LIMIT;
    286
    287 --插入数据
    288 /*FORALL I IN MY_TAB.FIRST .. MY_TAB.COUNT
    289 INSERT INTO D VALUES (MY_TAB(I));
    290 EXIT WHEN V_CURSOR%NOTFOUND;*/
    291
    292 --更新数据
    293 /* FORALL I IN MY_TAB.FIRST .. MY_TAB.COUNT
    294 UPDATE D SET IDS = 'HAHA' WHERE IDS = MY_TAB(I);
    295 EXIT WHEN V_CURSOR%NOTFOUND;*/
    296
    297 --删除数据
    298 FORALL I IN MY_TAB.FIRST .. MY_TAB.COUNT
    299 DELETE FROM D WHERE IDS = MY_TAB(I);
    300 EXIT WHEN V_CURSOR%NOTFOUND;
    301
    302 END LOOP;
    303 CLOSE V_CURSOR;
    304 DBMS_OUTPUT.PUT_LINE(MY_TAB.COUNT);
    305
    306 COMMIT;
    307 --异常处理
    308 EXCEPTION
    309 WHEN OTHERS THEN
    310 O_RETURN_FLAG := 'E' || '_' || SQLCODE || '_' || SQLERRM;
    311 RETURN;
    312 END;
    313
    314 /***********************************************************
    315 *测试FORALL的INDICES使用
    316 ************************************************************/
    317 PROCEDURE TEST_INDICES(O_RETURN_FLAG OUT VARCHAR2) IS
    318 TYPE TYPE_TAB IS TABLE OF VARCHAR2(100) INDEX BY PLS_INTEGER;
    319 MY_TAB TYPE_TAB;
    320 BEGIN
    321 O_RETURN_FLAG := 'S';
    322 --初始化联合数组
    323 MY_TAB(1) := 'A';
    324 MY_TAB(2) := 'B';
    325 MY_TAB(3) := 'C';
    326 MY_TAB(4) := 'D';
    327 MY_TAB(5) := 'E';
    328 MY_TAB(6) := 'G';
    329 MY_TAB(7) := 'H';
    330
    331 FOR IDX IN MY_TAB.FIRST .. MY_TAB.COUNT LOOP
    332 IF MY_TAB(IDX) = 'A' THEN
    333 MY_TAB.DELETE(IDX);
    334 ELSIF MY_TAB(IDX) = 'D' THEN
    335 MY_TAB.DELETE(IDX);
    336 ELSE
    337 NULL;
    338 END IF;
    339 END LOOP;
    340 --使用FORALL插入数据
    341 FORALL IDX IN INDICES OF MY_TAB
    342 INSERT INTO D VALUES (MY_TAB(IDX));
    343 COMMIT;
    344
    345 EXCEPTION
    346 WHEN OTHERS THEN
    347 O_RETURN_FLAG := 'E' || '_' || SQLCODE || '_' || SQLERRM;
    348 ROLLBACK;
    349 RETURN;
    350 END;
    351
    352 /***********************************************************
    353 *FORALL操作的过程中的异常处理
    354 ************************************************************/
    355 PROCEDURE TEST_EXCEPTION(O_RETURN_FLAG OUT VARCHAR2) IS
    356 --dml_exp EXCEPTION;
    357 --定义异常
    358 --PRAGMA EXCEPTION_INIT(dml_exp,01403);
    359 ERRORS PLS_INTEGER;
    360 TYPE TYPE_TAB IS TABLE OF VARCHAR2(100) INDEX BY PLS_INTEGER;
    361 MY_TAB TYPE_TAB;
    362
    363 BEGIN
    364 O_RETURN_FLAG := 'S';
    365 --初始化联合数组
    366 MY_TAB(1) := 'A';
    367 MY_TAB(2) := 'B';
    368 MY_TAB(3) := 'C';
    369 --MY_TAB(4) := 'D';
    370 MY_TAB(5) := 'E';
    371 MY_TAB(6) := 'F';
    372 MY_TAB(7) := 'F';
    373
    374 --使用FORALL插入数据
    375
    376 FORALL IDX IN MY_TAB.FIRST .. MY_TAB.COUNT SAVE EXCEPTIONS
    377 --INSERT INTO D VALUES (MY_TAB(IDX));
    378 DELETE FROM D WHERE D.IDS = MY_TAB(IDX);
    379 COMMIT;
    380
    381 /* FORALL IDX IN INDICES OF MY_TAB SAVE EXCEPTIONS
    382 --INSERT INTO D VALUES (MY_TAB(IDX));
    383 DELETE FROM d WHERE d.ids = MY_TAB(IDX);
    384 COMMIT;*/
    385
    386 EXCEPTION
    387 WHEN OTHERS THEN
    388 O_RETURN_FLAG := 'E' || '_' || SQLCODE || '_' || SQLERRM;
    389 ROLLBACK;
    390 ERRORS := SQL%BULK_EXCEPTIONS.COUNT;
    391 DBMS_OUTPUT.PUT_LINE('FAIL NUMS IS ' || ERRORS);
    392 FOR IDX IN 1 .. ERRORS LOOP
    393 DBMS_OUTPUT.PUT_LINE('error at ' || SQL%BULK_EXCEPTIONS(IDX)
    394 .ERROR_INDEX || 'error info is ' || SQL%BULK_EXCEPTIONS(IDX)
    395 .ERROR_CODE);
    396 END LOOP;
    397 RETURN;
    398
    399 END;

    接上面的部分:

      1  /***********************************************************
    2 *快速插入数据(常用方法)
    3 ************************************************************/
    4 PROCEDURE TEST_INSERT_GENERAL(O_RETURN_FLAG OUT VARCHAR2) IS
    5 BEGIN
    6 O_RETURN_FLAG := 'S';
    7 FOR IDX IN (SELECT * FROM ALL_OBJECTS) LOOP
    8 INSERT INTO D VALUES (IDX.OBJECT_NAME);
    9 END LOOP;
    10 --异常处理
    11 EXCEPTION
    12 WHEN OTHERS THEN
    13 O_RETURN_FLAG := 'E' || '_' || SQLCODE || '_' || SQLERRM;
    14 RETURN;
    15 END;
    16
    17 --快速插入数据1、使用VARRAY TABLE
    18 PROCEDURE TEST_INSERT_FAST1(O_RETURN_FLAG OUT VARCHAR2) IS
    19 TYPE TYP_TAB IS TABLE OF USER_OBJECTS.OBJECT_NAME%TYPE;
    20 TYPE TYP_TAB_ROW IS TABLE OF E%ROWTYPE;
    21 MY_TAB TYP_TAB;
    22 MY_TAB_ROW TYP_TAB_ROW;
    23 CURSOR C IS
    24 SELECT OBJECT_NAME FROM USER_OBJECTS;
    25 CURSOR D_CURSOR IS
    26 SELECT D.IDS FROM D;
    27 BEGIN
    28 O_RETURN_FLAG := 'S';
    29 OPEN C;
    30 LOOP
    31 FETCH C BULK COLLECT
    32 INTO MY_TAB LIMIT 100;
    33
    34 FOR IDX IN MY_TAB.FIRST .. MY_TAB.LAST LOOP
    35 MY_TAB(IDX) := MY_TAB(IDX) || 'HAHA';
    36 DBMS_OUTPUT.PUT_LINE(IDX);
    37 END LOOP;
    38
    39 --FORALL处理
    40 FORALL I IN MY_TAB.FIRST .. MY_TAB.COUNT
    41 INSERT INTO D VALUES (MY_TAB(I));
    42 DBMS_OUTPUT.PUT_LINE(MY_TAB.COUNT);
    43
    44 EXIT WHEN C%NOTFOUND;
    45
    46 END LOOP;
    47 CLOSE C;
    48 COMMIT;
    49
    50 --插入ROWTYPE类型的数据
    51 OPEN D_CURSOR;
    52 LOOP
    53 FETCH D_CURSOR BULK COLLECT
    54 INTO MY_TAB_ROW LIMIT 100;
    55
    56 FOR IDX IN MY_TAB_ROW.FIRST .. MY_TAB_ROW.LAST LOOP
    57 MY_TAB_ROW(IDX).IDS := MY_TAB_ROW(IDX).IDS || 'HAHA';
    58 END LOOP;
    59
    60 --FORALL处理
    61 FORALL I IN MY_TAB_ROW.FIRST .. MY_TAB_ROW.COUNT
    62 INSERT INTO E VALUES MY_TAB_ROW (I);
    63 EXIT WHEN D_CURSOR%NOTFOUND;
    64
    65 END LOOP;
    66 CLOSE D_CURSOR;
    67 COMMIT;
    68
    69 --异常处理
    70 EXCEPTION
    71 WHEN OTHERS THEN
    72 O_RETURN_FLAG := 'E' || '_' || SQLCODE || '_' || SQLERRM;
    73 RETURN;
    74 END;
    75
    76 /***********************************************************
    77 *快速插入数据2、使用联合数组
    78 ************************************************************/
    79
    80 PROCEDURE TEST_INSERT_FAST2(O_RETURN_FLAG OUT VARCHAR2) IS
    81 TYPE TYP_TAB IS TABLE OF USER_OBJECTS.OBJECT_NAME%TYPE INDEX BY PLS_INTEGER;
    82 MY_TAB TYP_TAB;
    83 CURSOR C IS
    84 SELECT OBJECT_NAME FROM ALL_OBJECTS;
    85 BEGIN
    86 O_RETURN_FLAG := 'S';
    87 OPEN C;
    88 LOOP
    89 FETCH C BULK COLLECT
    90 INTO MY_TAB LIMIT 100;
    91
    92 FOR IDX IN MY_TAB.FIRST .. MY_TAB.LAST LOOP
    93 MY_TAB(IDX) := MY_TAB(IDX) || 'HAHA';
    94 END LOOP;
    95 --FORALL处理
    96 FORALL I IN MY_TAB.FIRST .. MY_TAB.COUNT
    97 INSERT INTO D VALUES (MY_TAB(I));
    98 EXIT WHEN C%NOTFOUND;
    99
    100 END LOOP;
    101 CLOSE C;
    102 COMMIT;
    103 --异常处理
    104 EXCEPTION
    105 WHEN OTHERS THEN
    106 O_RETURN_FLAG := 'E' || '_' || SQLCODE || '_' || SQLERRM;
    107 RETURN;
    108 END;
    109
    110 /***********************************************************
    111 *批量插入数据,一条一条的处理:使用VARRAY
    112 ************************************************************/
    113 PROCEDURE TEST_BATCH_1(I_NAME IN VARCHAR2, O_RETURN_FLAG OUT VARCHAR2) IS
    114 V_LIMIT CONSTANT NUMBER := 10;
    115 TYPE TYE_RECORD IS RECORD(
    116 DEPTNO NUMBER(2),
    117 DNAME VARCHAR2(14),
    118 LOC VARCHAR2(13),
    119 RID UROWID);
    120 DEPT_CURSOR SYS_REFCURSOR;
    121 --定义VARRAY类型
    122 TYPE DEPT_VARRAY IS VARRAY(10) OF TYE_RECORD;
    123 --定义VARRAY的变量
    124 RESULTS DEPT_VARRAY;
    125 V_SQL VARCHAR2(100) := 'SELECT DEPTNO, DNAME, LOC,ROWID FROM DEPT WHERE DEPTNO = :1';
    126 BEGIN
    127 --打开带绑定变量的游标
    128 OPEN DEPT_CURSOR FOR V_SQL
    129 USING 30;
    130 --提取数据
    131 FETCH DEPT_CURSOR BULK COLLECT
    132 INTO RESULTS LIMIT V_LIMIT;
    133 --循环数据
    134 LOOP
    135 FOR IDX IN 1 .. RESULTS.COUNT LOOP
    136 --更新数据
    137 EXECUTE IMMEDIATE 'UPDATE DEPT SET DEPT.DNAME = :1 WHERE DEPT.ROWID =:2'
    138 USING I_NAME, RESULTS(IDX).RID;
    139 END LOOP;
    140 EXIT WHEN RESULTS.COUNT < V_LIMIT;
    141 END LOOP;
    142 --异常处理
    143 EXCEPTION
    144 WHEN OTHERS THEN
    145 O_RETURN_FLAG := 'E' || '_' || SQLCODE || '_' || SQLERRM;
    146 RETURN;
    147 END;
    148
    149 /***********************************************************
    150 *批量插入数据,一条一条的处理:使用联合数组
    151 ************************************************************/
    152 PROCEDURE TEST_BATCH_2(I_NAME IN VARCHAR2, O_RETURN_FLAG OUT VARCHAR2) IS
    153
    154 V_LIMIT CONSTANT NUMBER := 10;
    155 TYPE TYP_RID IS TABLE OF UROWID INDEX BY BINARY_INTEGER;
    156 RIDS TYP_RID;
    157 DEPT_CURSOR SYS_REFCURSOR;
    158 V_SQL VARCHAR2(100) := 'SELECT ROWID FROM DEPT WHERE DEPTNO = :1';
    159 BEGIN
    160 --打开带绑定变量的游标
    161 OPEN DEPT_CURSOR FOR V_SQL
    162 USING 30;
    163 --提取数据
    164 LOOP
    165 FETCH DEPT_CURSOR BULK COLLECT
    166 INTO RIDS LIMIT V_LIMIT;
    167 --FORALL处理数据
    168 FORALL IDX IN 1 .. RIDS.COUNT EXECUTE IMMEDIATE
    169 'UPDATE DEPT SET DEPT.DNAME = :1 WHERE DEPT.ROWID =:2'
    170 USING I_NAME, RIDS(IDX)
    171 ;
    172 EXIT WHEN RIDS.COUNT < V_LIMIT;
    173 END LOOP;
    174
    175 --异常处理
    176 EXCEPTION
    177 WHEN OTHERS THEN
    178 O_RETURN_FLAG := 'E' || '_' || SQLCODE || '_' || SQLERRM;
    179 RETURN;
    180 END;
    181
    182 BEGIN
    183 NULL;
    184 END TEST_REF_CURSOR;




     

    I believe that we are who we choose to be. Nobody‘s going to come and save you, you‘ve got to save yourself. 我相信我们成为怎样的人是我们自己的选择。没有人会来拯救你,你必须要自己拯救自己。
  • 相关阅读:
    P2731 骑马修栅栏 Riding the Fences
    P1351 联合权值
    [脚本]为所有节点挂载磁盘
    [转]expect的安装
    挂载磁盘linux
    [转]Mac 科研常用软件
    [转]error while loading shared libraries 错误解决办法总结
    linux安装SVN
    Java web项目在linux环境下自动编译和部署脚本
    个人所得税计算方法
  • 原文地址:https://www.cnblogs.com/caroline/p/2321052.html
Copyright © 2011-2022 走看看