多條sql執行時如果在中間的語句出現錯誤,后續會不會直接執行,如何進行設定,以及其他數據庫諸如MySQL是如何對應的,這篇文章將會進行簡單的整理和說明。
環境準備
使用Oracle的精簡版創建docker方式的demo環境。
多行語句的正常執行
對上篇文章創建的兩個字段的學生信息表,正常添加三條數據,詳細如下:
# sqlplus system/liumiao123@XE <<EOF>descstudent>select*fromstudent;>insertintostudentvalues(1001,'liumiaocn');>insertintostudentvalues(1002,'liumiao');>insertintostudentvalues(1003,'michael');>commit;>select*fromstudent;> EOFSQL*Plus: Release 11.2.0.2.0 ProductiononSun Oct 21 12:08:35 2018Copyright (c) 1982, 2011, Oracle.Allrights reserved.Connectedto:OracleDatabase11g Express Edition Release 11.2.0.2.0 - 64bit ProductionSQL>NameNull? Type----------------------------------------- -------- ----------------------------STUIDNOTNULLNUMBER(4)STUNAME VARCHAR2(50)SQL>norowsselectedSQL>1 row created.SQL>1 row created.SQL>1 row created.SQL>Commitcomplete.SQL>STUID STUNAME---------- --------------------------------------------------1001 liumiaocn1002 liumiao1003 michaelSQL> DisconnectedfromOracleDatabase11g Express Edition Release 11.2.0.2.0 - 64bit Production#
多行語句中間出錯時的缺省動作
問題:
三行insert語句,如果中間的一行出錯,缺省的狀況下第三行會不會被插入進去?
我們將第二條insert語句的主鍵故意設定重復,然后進行確認第三條數據是否會進行插入即可。
# sqlplus system/liumiao123@XE <<EOFdescstudentdeletefromstudent;select*fromstudent;insertintostudentvalues(1001,'liumiaocn');insertintostudentvalues(1001,'liumiao');insertintostudentvalues(1003,'michael');select*fromstudent;commit;> > > > >> EOFSQL*Plus: Release 11.2.0.2.0 ProductiononSun Oct 21 12:15:16 2018Copyright (c) 1982, 2011, Oracle.Allrights reserved.Connectedto:OracleDatabase11g Express Edition Release 11.2.0.2.0 - 64bit ProductionSQL>NameNull? Type----------------------------------------- -------- ----------------------------STUIDNOTNULLNUMBER(4)STUNAME VARCHAR2(50)SQL>2rowsdeleted.SQL>norowsselectedSQL>1 row created.SQL>insertintostudentvalues(1001,'liumiao')*ERRORatline 1:ORA-00001:uniqueconstraint(SYSTEM.SYS_C007024) violatedSQL>1 row created.SQL>STUID STUNAME---------- --------------------------------------------------1001 liumiaocn1003 michaelSQL> SQL> DisconnectedfromOracleDatabase11g Express Edition Release 11.2.0.2.0 - 64bit Production#
結果非常清晰地表明是會繼續執行的,在oracle中通過什么來對其進行控制呢?
WHENEVER SQLERROR
答案很簡單,在oracle中通過WHENEVER SQLERROR來進行控制。
WHENEVER SQLERROR {EXIT [SUCCESS | FAILURE | WARNING | n | variable | :BindVariable] [COMMIT | ROLLBACK] | CONTINUE [COMMIT | ROLLBACK | NONE]}
WHENEVER SQLERROR EXIT
添加此行設定,即會在失敗的時候立即推出,接下來我們進行確認:
# sqlplus system/liumiao123@XE <<EOFWHENEVER SQLERROR EXITdescstudentdeletefromstudent;select*fromstudent;insertintostudentvalues(1001,'liumiaocn');insertintostudentvalues(1001,'liumiao');insertintostudentvalues(1003,'michael');select*fromstudent;commit;> > > > > > > > >> EOFSQL*Plus: Release 11.2.0.2.0 ProductiononSun Oct 21 12:27:15 2018Copyright (c) 1982, 2011, Oracle.Allrights reserved.Connectedto:OracleDatabase11g Express Edition Release 11.2.0.2.0 - 64bit ProductionSQL> SQL>NameNull? Type----------------------------------------- -------- ----------------------------STUIDNOTNULLNUMBER(4)STUNAME VARCHAR2(50)SQL>2rowsdeleted.SQL>norowsselectedSQL>1 row created.SQL>insertintostudentvalues(1001,'liumiao')*ERRORatline 1:ORA-00001:uniqueconstraint(SYSTEM.SYS_C007024) violatedDisconnectedfromOracleDatabase11g Express Edition Release 11.2.0.2.0 - 64bit Production#
WHENEVER SQLERROR CONTINUE
使用CONTINUE則和缺省方式下的行為一致,出錯仍然繼續執行
# sqlplus system/liumiao123@XE <<EOFWHENEVER SQLERRORCONTINUEdescstudentdeletefromstudent;select*fromstudent;insertintostudentvalues(1001,'liumiaocn');insertintostudentvalues(1001,'liumiao');insertintostudentvalues(1003,'michael');select*fromstudent;commit;> > > > > > > > >> EOFSQL*Plus: Release 11.2.0.2.0 ProductiononSun Oct 21 12:31:54 2018Copyright (c) 1982, 2011, Oracle.Allrights reserved.Connectedto:OracleDatabase11g Express Edition Release 11.2.0.2.0 - 64bit ProductionSQL> SQL>NameNull? Type----------------------------------------- -------- ----------------------------STUIDNOTNULLNUMBER(4)STUNAME VARCHAR2(50)SQL>1 row deleted.SQL>norowsselectedSQL>1 row created.SQL>insertintostudentvalues(1001,'liumiao')*ERRORatline 1:ORA-00001:uniqueconstraint(SYSTEM.SYS_C007024) violatedSQL>1 row created.SQL>STUID STUNAME---------- --------------------------------------------------1001 liumiaocn1003 michaelSQL>Commitcomplete.SQL> DisconnectedfromOracleDatabase11g Express Edition Release 11.2.0.2.0 - 64bit Production#
Mysql中類似的機制
mysql中使用source是否提供相關的類似機制的問題中,最終引入了Oracle此項功能在mysql中引入的建議,詳細請參看:
https://bugs.mysql.com/bug.php?id=73177所以目前這只是一個sqlplus端的強化功能,并非標準,不同數據庫需要確認相應的功能是否存在。
小結
Oracle中使用WHENEVER SQLERROR進行出錯控制是否繼續,本文給出的例子非常簡單,詳細功能的使用可根據文中列出的Usage進行自行驗證和探索。
總結
以上就是Oracle數據庫多條sql執行語句出現錯誤時的控制方式的全部內容了,希望本文的內容對大家的學習或者工作具有一定的參考學習價值。











