![]() | |
![]() |
| | Thread Tools | Display Modes |
#1
| |||
| |||
|
#2
| |||
| |||
|
|
just run into a problem with Oracle 9i running on Linux If my exceptin handlers don't reraise exceptions, all works as expected: CREATE TABLE AAT(N NUMBER NOT NULL PRIMARY KEY) Table created CREATE TABLE AAT11(errMessage VARCHAR2(30), N NUMBER) Table created / CREATE OR REPLACE PROCEDURE AAT_TEST(P_N IN NUMBER) AS PK_violation EXCEPTION; PRAGMA EXCEPTION_INIT(PK_violation, -1); BEGIN INSERT INTO AAT VALUES(P_N); IF(P_N = 2) THEN RAISE_APPLICATION_ERROR(-20001, 'My custom exception'); END IF; EXCEPTION WHEN PK_violation THEN INSERT INTO AAT11 VALUES('PK_violation', P_N); WHEN OTHERS THEN INSERT INTO AAT11 VALUES('OTHERS', P_N); -- RAISE; END; Procedure created --------- should succeed - CALL AAT_TEST(1) Method called -------- should be PK violation CALL AAT_TEST(1) Method called -------- shiould be my custom exception CALL AAT_TEST(2) Method called SELECT * FROM AAT N ---------- 1 2 2 rows selected SELECT * FROM AAT11 ERRMESSAGE N ------------------------------ ---------- PK_violation 1 OTHERS 2 2 rows selected Hopwever, if I uncomment RAISE, the results are a little bit surprising: CREATE OR REPLACE PROCEDURE AAT_TEST(P_N IN NUMBER) AS PK_violation EXCEPTION; PRAGMA EXCEPTION_INIT(PK_violation, -1); BEGIN INSERT INTO AAT VALUES(P_N); IF(P_N = 2) THEN RAISE_APPLICATION_ERROR(-20001, 'My custom exception'); END IF; EXCEPTION WHEN PK_violation THEN INSERT INTO AAT11 VALUES('PK_violation', P_N); WHEN OTHERS THEN INSERT INTO AAT11 VALUES('OTHERS', P_N); RAISE; END; Procedure created CALL AAT_TEST(1) Method called CALL AAT_TEST(1) Method called CALL AAT_TEST(2) ORA-20001: My custom exception ORA-06512: at "********.AAT_TEST", line 18 SELECT * FROM AAT N ---------- 1 1 row selected SELECT * FROM AAT11 ERRMESSAGE N ------------------------------ ---------- PK_violation 1 1 row selected ROLLBACK Rollback complete SELECT * FROM AAT 0 rows selected SELECT * FROM AAT11 0 rows selected it looks as if Oracle implicitly added a savepoint before CALL AAT_TEST(2) and issued a ROLLBACK to that savepoint when the SP call failed. I don't want DML performed by the SP to be rolled back. Are there any ways to accomplish it? I'm not a student, this is a problem in production |
#3
| |||
| |||
|
#4
| |||
| |||
|
|
just run into a problem with Oracle 9i running on Linux If my exceptin handlers don't reraise exceptions, all works as expected: |
|
CREATE TABLE AAT(N NUMBER NOT NULL PRIMARY KEY) Table created CREATE TABLE AAT11(errMessage VARCHAR2(30), N NUMBER) Table created / CREATE OR REPLACE PROCEDURE AAT_TEST(P_N IN NUMBER) AS PK_violation EXCEPTION; PRAGMA EXCEPTION_INIT(PK_violation, -1); BEGIN INSERT INTO AAT VALUES(P_N); IF(P_N = 2) THEN RAISE_APPLICATION_ERROR(-20001, 'My custom exception'); END IF; EXCEPTION WHEN PK_violation THEN INSERT INTO AAT11 VALUES('PK_violation', P_N); WHEN OTHERS THEN INSERT INTO AAT11 VALUES('OTHERS', P_N); -- RAISE; END; Procedure created --------- should succeed - CALL AAT_TEST(1) Method called -------- should be PK violation CALL AAT_TEST(1) Method called -------- shiould be my custom exception CALL AAT_TEST(2) Method called SELECT * FROM AAT N ---------- 1 2 2 rows selected SELECT * FROM AAT11 ERRMESSAGE N ------------------------------ ---------- PK_violation 1 OTHERS 2 2 rows selected Hopwever, if I uncomment RAISE, the results are a little bit surprising: CREATE OR REPLACE PROCEDURE AAT_TEST(P_N IN NUMBER) AS PK_violation EXCEPTION; PRAGMA EXCEPTION_INIT(PK_violation, -1); BEGIN INSERT INTO AAT VALUES(P_N); IF(P_N = 2) THEN RAISE_APPLICATION_ERROR(-20001, 'My custom exception'); END IF; EXCEPTION WHEN PK_violation THEN INSERT INTO AAT11 VALUES('PK_violation', P_N); WHEN OTHERS THEN INSERT INTO AAT11 VALUES('OTHERS', P_N); RAISE; END; Procedure created CALL AAT_TEST(1) Method called CALL AAT_TEST(1) Method called CALL AAT_TEST(2) ORA-20001: My custom exception ORA-06512: at "********.AAT_TEST", line 18 SELECT * FROM AAT N ---------- 1 1 row selected SELECT * FROM AAT11 ERRMESSAGE N ------------------------------ ---------- PK_violation 1 1 row selected ROLLBACK Rollback complete SELECT * FROM AAT 0 rows selected SELECT * FROM AAT11 0 rows selected it looks as if Oracle implicitly added a savepoint before CALL AAT_TEST(2) and issued a ROLLBACK to that savepoint when the SP call failed. I don't want DML performed by the SP to be rolled back. Are there any ways to accomplish it? I'm not a student, this is a problem in production |
#5
| |||
| |||
|
|
all statements are atomic. sql> exec foo; that either 100% succeeds or 100% fails. (yes, there is an implicit savepoint in there to make everything atomic) |
#6
| |||
| |||
|
|
all statements are atomic. sql> exec foo; that either 100% succeeds or 100% fails. (yes, there is an implicit savepoint in there to make everything atomic) Thanks Tom I have an SP issuing several DML commands. in the procedure that called the failed one, I wanted to figure out which DML failed, and I noticed that changes made by a failed SP are rolled back. I did not know why, and I was very curious. I guessed there is an implicit savepoint. Thank you for confirming that. Recording which DML has failed is very easy: V_STEP VARCHAR2(20); ... V_STEP := 'INSERT INTO TABLE1'; INSERT INTO TABLE1 ... V_STEP := 'INSERT INTO TABLE2'; INSERT INTO TABLE2 ... ... EXCEPTION WHEN OTHERS THEN SD_LOG_SQL_ERROR(SQLCODE, SQLERRM, 'My_SP_Name '|| V_STEP, TRIM(My_SP_parameters)); ROLLBACK; RAISE; I've described SD_LOG_SQL_ERROR in my previous post. |
#7
| |||
| |||
|
#8
| |||
| |||
|
|
Thanks Tom, the only difference between your procedure and mine that I noticed is that yours is in lowercase while mine is in uppercase. Are you suggesting that uppercase SQL is bad programming style? |
#9
| |||
| |||
|
|
In article <1103236627.680720.19790 (AT) c13g2000cwb (DOT) googlegroups.com>, ford_desperado (AT) yahoo (DOT) com says... Thanks Tom, the only difference between your procedure and mine that I noticed is that yours is in lowercase while mine is in uppercase. Are you suggesting that uppercase SQL is bad programming style? No, the big difference is a) pragma autonomous_transaction; b) commit; (but no, I am personally not a fan of uppercase in code, I find it miserable hard to read for some reason... but that is a matter of opinion) -- Thomas Kyte Oracle Public Sector http://asktom.oracle.com/ opinions are my own and may not reflect those of Oracle Corporation |
#10
| |||
| |||
|
| "Thomas Kyte" <tkyte (AT) oracle (DOT) com> wrote in message news:113244507.000080c5.074 (AT) drn (DOT) newsguy.com... In article <1103236627.680720.19790 (AT) c13g2000cwb (DOT) googlegroups.com>, ford_desperado (AT) yahoo (DOT) com says... Thanks Tom, the only difference between your procedure and mine that I noticed is that yours is in lowercase while mine is in uppercase. Are you suggesting that uppercase SQL is bad programming style? No, the big difference is a) pragma autonomous_transaction; b) commit; (but no, I am personally not a fan of uppercase in code, I find it miserable hard to read for some reason... but that is a matter of opinion) -- Thomas Kyte Oracle Public Sector http://asktom.oracle.com/ opinions are my own and may not reflect those of Oracle Corporation bit ott, but whats public sector- different that Government health and education? |

![]() |
| Thread Tools | |
| Display Modes | |
| |