在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;
/
通过在异常处理程序中记录异常信息或采取适当的措施,你可以保证即使在循环中出现异常,程序也能继续进行下一次迭代。
请注意,对于很多情况来说,考虑在处理后继续执行之前,确保已解决异常引发的问题是非常重要的。