首页 » ORACLE 9i-23ai » 如何在oracle PL/SQL loop中捕获异常Exception继续?
如何在oracle PL/SQL loop中捕获异常Exception继续?
在Oracle PL/SQL中,在循环中捕获异常并继续执行可以通过使用异常块实现。如循环kill session 可能会遇到session marked killed报错中断,或flush shared pool 中的sql时,因为有部分sql keep, 遍历时会遇到ora-6596 错误 ,下面是一个简单的示例,演示了如何在PL/SQL循环中捕获异常并继续执行:
BEGIN
FOR i IN 1..10 LOOP
BEGIN
-- 在这里放置你的代码,可能会引发异常
NULL; -- 举例:这里是你的实际代码
EXCEPTION
WHEN others THEN
-- 在这里处理或记录异常
dbms_output.put_line('Exception occurred, but continuing loop iteration: ' || SQLERRM);
END;
END LOOP;
END;
在上述示例中,FOR
循环内部包含一个 BEGIN ... END
块,该块包含实际的逻辑代码。如果任何一个循环迭代中的代码引发异常,异常将被捕获并在 EXCEPTION
块中处理。WHEN others
表示捕获所有类型的异常,但是最好在实际情况中根据需要更具体地捕获异常。
如kill tx blocker session
declare blockcount number; sqlreport varchar(3000); sqloutput varchar(5000); v_rec varchar(3000); v_sql varchar(2000); cursor blk_curs is select s.USERNAME BUSER,s.SID BSID,s.SERIAL# BSERIAL,s.STATUS BSTAT,s.program,s.LAST_CALL_ET BLAST from dba_waiters w,v$session s where w.lock_type='Transaction' and W.HOLDING_SESSION=s.SID and s.username not in ('SYSTEM','DBSNMP','RMAN') and s.last_call_et>=60; begin DBMS_OUTPUT.put_line('Checking for blocking sessions on this database'); DBMS_OUTPUT.put_line('-----------------------------------------------'); select count(*) into blockcount from dba_blockers; IF blockcount > 0 THEN DBMS_OUTPUT.put_line('Found blocking sessions -> Fetching report for the same'); DBMS_OUTPUT.put_line('-------------------------------------------------------'); for v_rec in blk_curs LOOP dbms_output.put_line('Blocker: ('||v_rec.BUSER ||' program'||v_rec.program||' ('||v_rec.BSID||','||v_rec.BSERIAL||') is Currently '||v_rec.BSTAT||' for last '||v_rec.BLAST||' Sec '||')'); end loop; DBMS_OUTPUT.put_line('-'); DBMS_OUTPUT.put_line('-'); DBMS_OUTPUT.put_line('Further details on blocking sessions -> includes kill script of blocking session'); DBMS_OUTPUT.put_line('--------------------------------------------------------------------------------'); for v_rec in blk_curs LOOP BEGIN v_sql:='alter system kill session ''' || v_rec.BSID || ', ' || v_rec.BSERIAL || '''immediate'; DBMS_OUTPUT.put_line(v_sql); -- execution kill execute immediate v_sql; EXCEPTION WHEN OTHERS THEN DBMS_OUTPUT.PUT_LINE (SQLCODE); END; end loop; DBMS_OUTPUT.put_line('-'); DBMS_OUTPUT.put_line('-'); ELSE DBMS_OUTPUT.put_line('-'); DBMS_OUTPUT.put_line('-'); DBMS_OUTPUT.put_line('Hurrey !!! No blocking sessions found'); DBMS_OUTPUT.put_line('-'); DBMS_OUTPUT.put_line('-'); END IF; EXCEPTION WHEN OTHERS THEN DBMS_OUTPUT.PUT_LINE (SQLCODE); END;
flush shared pool SQL
DECLARE curstr VARCHAR2 (300); BEGIN FOR cur IN (SELECT address, hash_value FROM v$sqlarea WHERE executions=1 AND LAST_LOAD_TIME < SYSDATE - 1/24 ) LOOP BEGIN curstr := 'begin sys.dbms_shared_pool.purge(:b1,''c'',65); end;'; -- DBMS_OUTPUT.put_line ('exec sys.dbms_shared_pool.purge('':b1,:b2'',''c'',65)'); EXECUTE IMMEDIATE (curstr) USING cur.address || ',' || cur.hash_value; EXCEPTION WHEN OTHERS THEN DBMS_OUTPUT.PUT_LINE (SQLCODE); END; END LOOP; END; /
通过在异常处理程序中记录异常信息或采取适当的措施,你可以保证即使在循环中出现异常,程序也能继续进行下一次迭代。
请注意,对于很多情况来说,考虑在处理后继续执行之前,确保已解决异常引发的问题是非常重要的。
对不起,这篇文章暂时关闭评论。