这是Pona的文章,我斗胆将其贴上来,Pona不要介意哦!^_^
PL/SQL里,有三种方法可以在处理大批量数据时不会因为一条或几条数据错误而导致异常中止程序。
1、用Fetch into a cursor%TYPE把要处理的数据放到记录集里。当一条数据不符条件时,用标签<
1<next_record>>和GOTO NEXT_RECORD跳转语句使程序忽略这一条,转到下一条继续处理。
2
3\-------------------------------------------------------------------------------
4
5\-- Function Name : CalculateImportCharge
6
7\-- Function Desc : Calculate Import Charge
8
9\-- Created by : Author
10
11\-- Created Date : 2003-05-16
12
13\-------------------------------------------------------------------------------
14
15FUNCTION CalculateImportCharge (
16
17p_i_job_id IN VARCHAR2,
18
19p_i_as_of_date_id IN VARCHAR2) RETURN NUMBER
20
21AS
22
23CURSOR cur_ShipBlHeader IS
24
25SELECT import_folder_no
26
27FROM GMY_SHIP_BL_HEADER
28
29WHERE CANCEL_FLG = GMY_GA000_PKG.BL_CANCEL_FLG_OFF;
30
31rec_ShipBlHeader cur_ShipBlHeader%ROWTYPE;
32
33BEGIN
34
35OPEN cur_ShipBlHeader;
36
37FETCH cur_ShipBlHeader INTO rec_ShipBlHeader;
38
39WHILE cur_ShipBlHeader%FOUND LOOP
40
41x_num_error_code := GMY_GA000_PKG.CheckValidMasterBlNo (
42
43p_i_job_id,
44
45p_i_as_of_date_id,
46
47rec_ShipBlHeader.import_folder_no,
48
49x_vch_message);
50
51IF x_num_error_code
52
53IN (GMY_GA000_PKG.gn#NG, GMY_GA000_PKG.INVALID_BL_NO) THEN
54
55x_vch_message :=
56
57p_i_job_id
58
59|| ' WARNING: Function CheckValidMasterBlNo @'
60
61|| ' Import folder '
62
63|| rec_ShipBlHeader.import_folder_no
64
65|| ' - Invalid BL No.';
66
67COM_LOG.PUTLINE (p_i_job_id, x_vch_message);
68
69GOTO NEXT_RECORD ;
70
71END IF;
72
73x_num_error_code := CheckExistsOfAccDate (
74
75p_i_job_id,
76
77p_i_as_of_date_id,
78
79rec_ShipBlHeader.import_folder_no);
80
81IF x_num_error_code = GMY_GA000_PKG.gn#NG THEN
82
83GOTO NEXT_RECORD ;
84
85END IF;
86
87COMMIT;
88
89<<next_record>>
90
91FETCH cur_ShipBlHeader INTO rec_ShipBlHeader;
92
93END LOOP ;
94
95CLOSE cur_ShipBlHeader;
96
97RETURN GMY_GA000_PKG.gn#OK;
98
99EXCEPTION
100
101WHEN OTHERS THEN
102
103x_vch_message :=
104
105p_i_job_id
106
107|| ' ERROR: Function CalculateImportCharge @ '
108
109|| SUBSTR (SQLERRM (SQLCODE), 1, 100);
110
111COM_LOG.PUTLINE (p_i_job_id, x_vch_message);
112
113RETURN GMY_GA000_PKG.gn#NG;
114
115END CalculateImportCharge;
116
1172、当使用the Cursor FOR Loop循环时,在Loop循环里,把会出问题的情况写进一个独立的block块中,这个块包括完整的begin、end部分及exception异常处理部分。这样即使一条数据出现异常,也会继续执行下一条。
118
119\-------------------------------------------------------------------------------
120
121\-- Function Name : GenerateInsCostInfRec
122
123\-- Function Desc : Generate records to transmit in INF table
124
125\-- Created by : SISS(AP)
126
127\-- Created Date : 2003-03-26
128
129\-- ----------------------------------------------------------------------------
130
131FUNCTION GenerateInsCostInfRec (
132
133p_i_job_id IN VARCHAR2,
134
135p_i_as_of_date_id IN VARCHAR2) RETURN NUMBER
136
137AS
138
139CURSOR cur_cost IS
140
141SELECT cost.ROWID costRowId,
142
143cost.import_folder_no,,
144
145cost.insur_trans_id
146
147FROM GMY_COST_BL cost,
148
149GMY_COMMON_MST mst
150
151WHERE cost.import_folder_no=invheader.import_folder_no
152
153AND cost.billing_amt_num IS NOT NULL
154
155AND cost.billing_amt_num!=0
156
157AND cost.insur_db_cr!=0;
158
159BEGIN
160
161FOR rec_cost IN cur_cost LOOP
162
163BEGIN
164
165x_num_ret_value := GMY_GA000_PKG.CheckValidMasterBlNo(
166
167p_i_job_id,
168
169p_i_as_of_date_id,
170
171rec_cost.import_folder_no,
172
173x_vch_error_msg);
174
175IF x_num_ret_value = GMY_GA000_PKG.VALID_BL_NO THEN
176
177INSERT INTO GMY_COST_INS_INF(
178
179cost_trx_id,,
180
181created_by,
182
183program_name)
184
185VALUES(
186
187GMY_COST_INS_INF_S.NEXTVAL,
188
189PRG_NAME,
190
191PRG_NAME);
192
193ELSIF x_num_ret_value = GMY_GA000_PKG.INVALID_BL_NO THEN
194
195x_vch_error_msg := p_i_job_id
196
197|| ' Import folder '
198
199|| rec_cost.import_folder_no
200
201|| ' has repeated BL No. with other import folder.'
202
203|| ' Failed in insurance cost transmission.';
204
205COM_LOG.PUTLINE(p_i_job_id, x_vch_error_msg);
206
207END IF;
208
209EXCEPTION
210
211WHEN OTHERS THEN
212
213IF SQL%ROWCOUNT > 0 THEN \-- check for 'too many rows'
214
215x_vch_error_msg := p_i_job_id||' '||
216
217SUBSTR(SQLERRM(SQLCODE),1,100);
218
219COM_LOG.PUTLINE(p_i_job_id, x_vch_error_msg);
220
221ELSE
222
223x_vch_error_msg := p_i_job_id||' '||
224
225SUBSTR(SQLERRM(SQLCODE),1,100);
226
227COM_LOG.PUTLINE(p_i_job_id, x_vch_error_msg);
228
229END IF;
230
231END;
232
233END LOOP ;
234
235COMMIT;
236
237RETURN GMY_GA000_PKG.gn#OK;
238
239EXCEPTION
240
241WHEN OTHERS THEN
242
243x_vch_error_msg := p_i_job_id||' '||SUBSTR(SQLERRM(SQLCODE),1,100);
244
245COM_LOG.PUTLINE(p_i_job_id, x_vch_error_msg);
246
247ROLLBACK;
248
249RETURN GMY_GA000_PKG.gn#NG;
250
251END GenerateInsCostInfRec;
252
2533、当使用the Cursor FOR Loop循环时,在Loop循环里,把会出问题的情况拆分成子函数,分别处理。
254
255\----------------------------------------------------------------------------
256
257\-- Function Name : CopyDsToActualDs
258
259\-- Function Desc : Copy the records from DS DB to Actual DS DB.
260
261\-- Created by : Author
262
263\-- Created Date : 2003-02-20
264
265\----------------------------------------------------------------------------
266
267FUNCTION CopyDsToActualDs (
268
269p_i_job_id IN VARCHAR2,
270
271p_i_as_of_date_id IN VARCHAR2) RETURN NUMBER
272
273IS
274
275CURSOR cur_DsScc IS
276
277SELECT *
278
279FROM GMY_DS_SCC;
280
281BEGIN
282
283FOR rec_DsHead IN cur_DsScc LOOP
284
285x_num_error_code := InsToActualScc(
286
287p_i_job_id,
288
289p_i_as_of_date_id,
290
291rec_DsHead.order_by_code,
292
293rec_DsHead.po_code,
294
295rec_DsHead.wh);
296
297END LOOP ;
298
299EXCEPTION
300
301WHEN OTHERS THEN
302
303x_vch_error_msg := p_i_job_id
304
305||' Function Name: CopyDsToActualDs';
306
307COM_LOG.PUTLINE(p_i_job_id,x_vch_error_msg);
308
309x_vch_error_msg:=p_i_job_id||' '||SUBSTR(SQLERRM(SQLCODE),1,100);
310
311COM_LOG.PUTLINE(p_i_job_id, x_vch_error_msg);
312
313ROLLBACK;
314
315RETURN GMY_GA000_PKG.gn#NG;
316
317END CopyDsToActualDs;
318
319\----------------------------------------------------------------------------
320
321\-- Function Name : InsToActualScc
322
323\-- Function Desc : Deal with insert section.
324
325\-- Created by : Author
326
327\-- Created Date : 2003-03-13
328
329\----------------------------------------------------------------------------
330
331FUNCTION InsToActualScc (
332
333p_i_job_id IN VARCHAR2,
334
335p_i_as_of_date_id IN VARCHAR2,
336
337p_i_order_by_code IN VARCHAR2,
338
339p_i_po_code IN VARCHAR2,
340
341p_i_wh IN VARCHAR2
342
343) RETURN NUMBER
344
345IS
346
347x_vch_error_msg VARCHAR2(255);
348
349BEGIN
350
351INSERT INTO GMY_ACTUAL_DS_SCC(
352
353order_by_code,
354
355po_code,
356
357wh )
358
359VALUES( p_i_order_by_code,
360
361p_i_po_code,
362
363p_i_wh);
364
365COMMIT;
366
367RETURN GMY_GA000_PKG.gn#OK;
368
369EXCEPTION
370
371WHEN OTHERS THEN
372
373x_vch_error_msg := p_i_job_id||' Function Name: InsToActualScc';
374
375COM_LOG.PUTLINE(p_i_job_id,x_vch_error_msg);
376
377x_vch_error_msg := p_i_job_id
378
379<SPAN lang=EN-US style="COLOR: black</next_record></next_record>