我有几个sql文件在这样的脚本中一个接一个地执行:
@script-A.sql;
@script-B.sql;
@script-C.sql;
...
每个脚本文件都有用,看起来像这样:
DECLARE
...
BEGIN
EXECUTE IMMEDIATE 'TRUNCATE SOME-TABLE';
-- lots of inserts into SOME_TABLE
COMMIT;
END;
/
我必须在一个大事务中包装sql文件。如果任何sql文件的执行失败,那么应该回滚所有以前的sql文件更改。
我该怎么做?
P.S
因为@Mat注意到DDL更改(truncate table)无法回滚。如果需要,我可以自由地重构这行代码。
答案 0 :(得分:1)
这里可以用来控制交易的最佳方式是 在每个脚本中保持异常处理,以便在任何情况下进行 事务失败,整个更改将被还原。唯一的 这里的条件是将COMMIT保持在最后,以便启用 成功交易最后一次火灾COMMIT。希望下面的片段 帮助
------------------------------Script 1-----------------------------------------
--Simple query to delete from records
DECLARE
p_err_cd PLS_INTEGER;
p_err_msg VARCHAR2(100 CHAR);
BEGIN
-- EXECUTE IMMEDIATE 'DELETE EMP ';
INSERT INTO EMP
SELECT '123', 'AVRJIT', 'DB', 12, SYSDATE, 1200, 123, 10, '123' FROM DUAL;
EXCEPTION
WHEN OTHERS THEN
ROLLBACK;
p_err_cd := SQLCODE;
p_err_msg:=SQLERRM;
dbms_output.put_line('Transaction Rollback');
END;
/
---------------------------------Script 2 ----------------------------------
--Simple query to delete from records
DECLARE
p_err_cd PLS_INTEGER;
p_err_msg VARCHAR2(100 CHAR);
BEGIN
-- EXECUTE IMMEDIATE 'DELETE EMP ';
INSERT INTO EMP
SELECT '123A', 'AVRJIT', 'DB', 12, SYSDATE, 1200, 123, 10, '123' FROM DUAL;
EXCEPTION
WHEN OTHERS THEN
ROLLBACK;
p_err_cd := SQLCODE;
p_err_msg:=SQLERRM;
dbms_output.put_line('Transaction Rollback');
END;
/
-----------------------------------------------------------------------------
Since EMP table has EMPNO as NUMBER field so the second script will fail.
While running the main executing file i.e Full_script.sql
set serveroutput on;
@C:\Av_test_script\Stack_overflow\full_script.sql
PL/SQL procedure successfully completed.
PL/SQL procedure successfully completed. --> Failed as EMPNO column here is of Invalid datatype
Transaction Rollback
答案 1 :(得分:0)
首先,您应该从代码中删除DDL并提交。然后在所有脚本执行后添加一个提交行。最后,您需要的是设置SQL * Plus参数以在firts错误上回滚您的事务。因此,您需要设置WHENEVER SQLERROR EXIT ROLLBACK
http://docs.oracle.com/cd/B19306_01/server.102/b14357/ch12052.htm
您可以在此处查看一些使用示例Oracle 11 - sqlplus - rollback the whole script on error - how?