测试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;




 

posted on 2012-01-12 22:03  Coldest Winter  阅读(814)  评论(0编辑  收藏  举报