• DB2 exception handling with rollback running simple scripts

    From nps.ferreira@gmail.com@21:1/5 to All on Wed Feb 7 06:35:53 2018
    Hi all,


    I've got some scripts that i want the ensure that runs without any error, and if any error occur the script rollback immediately.
    I'm a newbie in DB2, but I've got something similar in MS SQL Server, something like this:

    BEGIN TRANSACTION
    BEGIN TRY

    <SCRIPTS INSIDE>

    COMMIT
    PRINT 'COMMITED'
    END TRY
    BEGIN CATCH
    ROLLBACK
    PRINT 'ROLLED BACK'
    SELECT
    ERROR_NUMBER() AS ErrorNumber
    ,ERROR_SEVERITY() AS ErrorSeverity
    ,ERROR_STATE() AS ErrorState
    ,ERROR_PROCEDURE() AS ErrorProcedure
    ,ERROR_LINE() AS ErrorLine
    ,ERROR_MESSAGE() AS ErrorMessage;
    END CATCH

    But in DB2 there's nothing like this.
    I've tried to use SAVEPOINT and DECLARE EXIT HANDLER FOR SQLEXCEPTION but i got always error running this kind of script.
    Errors:

    An unexpected token "<space>" was found following "EXIT". Expected tokens may include: "HANDLER".. SQLCODE=-104, SQLSTATE=42601

    Anyone have a example script that does what i want to do?

    Cheers,

    Bigster

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From vvm13ru@gmail.com@21:1/5 to All on Wed Feb 7 22:29:45 2018
    I recommend to use something like that:

    db2 -f inputfile.sql -v -td@ -c- -s -m -q -l outputfileL.txt -r outputfileR.txt -z outputfileM.txt

    see "CLP options" at https://www.ibm.com/support/knowledgecenter/SSEPGG_10.5.0/com.ibm.db2.luw.admin.cmd.doc/doc/r0010410.html?pos=2

    You need
    -c- (or +c) and -s
    but other options also useful.

    Input file contains something like
    -- <SCRIPTS INSIDE>
    statement1 @
    statement2 @
    COMMIT @
    ECHO 'COMMITED'
    @

    No "BEGIN TRANSACTIONS", "TRY", "CATH" etc. You can control flow inside procedures, functions, triggers, but CLP scripts is very limited.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From nps.ferreira@gmail.com@21:1/5 to vvm...@gmail.com on Fri Feb 9 02:59:57 2018
    On Thursday, February 8, 2018 at 6:29:47 AM UTC, vvm...@gmail.com wrote:
    I recommend to use something like that:

    db2 -f inputfile.sql -v -td@ -c- -s -m -q -l outputfileL.txt -r outputfileR.txt -z outputfileM.txt

    see "CLP options" at https://www.ibm.com/support/knowledgecenter/SSEPGG_10.5.0/com.ibm.db2.luw.admin.cmd.doc/doc/r0010410.html?pos=2

    You need
    -c- (or +c) and -s
    but other options also useful.

    Input file contains something like
    -- <SCRIPTS INSIDE>
    statement1 @
    statement2 @
    COMMIT @
    ECHO 'COMMITED'
    @

    No "BEGIN TRANSACTIONS", "TRY", "CATH" etc. You can control flow inside procedures, functions, triggers, but CLP scripts is very limited.


    Hi,

    Thanks for your input.
    The only problem is that i must run the script inside a IDE (Data Studio) and the script you mention in to invoke in the CMD line.
    Like the script (in SQL Server) that i posted, i want to run it in the Database IDE.

    Any ideas how to achieve that?


    Cheers,

    Bigster

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Mark Barinstein@21:1/5 to All on Tue Feb 13 01:02:53 2018
    Hi,

    See the example below:

    --#SET TERMINATOR @
    --create table test (i int)@
    delete from test@

    begin atomic
    insert into test values 1;
    signal sqlstate '75000' set message_text='Exception 1';
    end@

    commit@

    begin
    -- Exit handler needed for DB2 CLP - it rollbacks a failed statement automatically
    -- if you want to have an ability to commit the 1-st insert
    --declare exit handler for sqlexception begin end;
    insert into test values 2;
    signal sqlstate '75000' set message_text='Exception 2';
    end@

    commit@

    begin
    declare exit handler for sqlexception
    begin
    ROLLBACK TO SAVEPOINT sp1;
    end;
    SAVEPOINT sp1 ON ROLLBACK RETAIN CURSORS;
    insert into test values 3;
    signal sqlstate '75000' set message_text='Exception 3';
    end@

    commit@

    select * from test@

    Regards,
    Mark

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From nps.ferreira@gmail.com@21:1/5 to Mark Barinstein on Mon Feb 19 04:05:59 2018
    Hi Mark,

    Thanks for your input.
    Your approach works but only with simple scripts, say inserts, updates etc..., but when i put a CREATE TABLE it fails.

    This is my example and the error:


    BEGIN
    DECLARE EXIT HANDLER FOR SQLEXCEPTION
    BEGIN
    ROLLBACK TO SAVEPOINT sp1;
    END;

    SAVEPOINT sp1 ON ROLLBACK RETAIN CURSORS;

    -- Create Tables
    CREATE TABLE CONFIG (
    CONFIG BIGINT NOT NULL GENERATED BY DEFAULT AS IDENTITY,
    CLIENT_ID BIGINT NOT NULL);

    signal sqlstate '75000' set message_text='Exception 3';
    END;

    Error:

    An unexpected token "<ddl-statement>" was found following "". Expected tokens may include: "".. SQLCODE=-104, SQLSTATE=42601, DRIVER=3.69.49
    An unexpected token "<ddl-statement>" was found following "". Expected tokens may include: "".. SQLCODE=-104, SQLSTATE=42601, DRIVER=3.69.49


    Any idea why?


    Cheers


    On Tuesday, February 13, 2018 at 9:02:56 AM UTC, Mark Barinstein wrote:
    Hi,

    See the example below:

    --#SET TERMINATOR @
    --create table test (i int)@
    delete from test@

    begin atomic
    insert into test values 1;
    signal sqlstate '75000' set message_text='Exception 1';
    end@

    commit@

    begin
    -- Exit handler needed for DB2 CLP - it rollbacks a failed statement automatically
    -- if you want to have an ability to commit the 1-st insert
    --declare exit handler for sqlexception begin end;
    insert into test values 2;
    signal sqlstate '75000' set message_text='Exception 2';
    end@

    commit@

    begin
    declare exit handler for sqlexception
    begin
    ROLLBACK TO SAVEPOINT sp1;
    end;
    SAVEPOINT sp1 ON ROLLBACK RETAIN CURSORS;
    insert into test values 3;
    signal sqlstate '75000' set message_text='Exception 3';
    end@

    commit@

    select * from test@

    Regards,
    Mark

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Mark Barinstein@21:1/5 to nps.fe...@gmail.com on Mon Feb 19 23:07:34 2018
    On Monday, February 19, 2018 at 3:06:03 PM UTC+3, nps.fe...@gmail.com wrote:
    Hi Mark,

    Thanks for your input.
    Your approach works but only with simple scripts, say inserts, updates etc..., but when i put a CREATE TABLE it fails.

    This is my example and the error:


    BEGIN
    DECLARE EXIT HANDLER FOR SQLEXCEPTION
    BEGIN
    ROLLBACK TO SAVEPOINT sp1;
    END;

    SAVEPOINT sp1 ON ROLLBACK RETAIN CURSORS;

    -- Create Tables
    CREATE TABLE CONFIG (
    CONFIG BIGINT NOT NULL GENERATED BY DEFAULT AS IDENTITY,
    CLIENT_ID BIGINT NOT NULL);

    signal sqlstate '75000' set message_text='Exception 3';
    END;

    Error:

    An unexpected token "<ddl-statement>" was found following "". Expected tokens may include: "".. SQLCODE=-104, SQLSTATE=42601, DRIVER=3.69.49
    An unexpected token "<ddl-statement>" was found following "". Expected tokens may include: "".. SQLCODE=-104, SQLSTATE=42601, DRIVER=3.69.49


    Any idea why?


    Cheers


    On Tuesday, February 13, 2018 at 9:02:56 AM UTC, Mark Barinstein wrote:
    Hi,

    See the example below:

    --#SET TERMINATOR @
    --create table test (i int)@
    delete from test@

    begin atomic
    insert into test values 1;
    signal sqlstate '75000' set message_text='Exception 1';
    end@

    commit@

    begin
    -- Exit handler needed for DB2 CLP - it rollbacks a failed statement automatically
    -- if you want to have an ability to commit the 1-st insert
    --declare exit handler for sqlexception begin end;
    insert into test values 2;
    signal sqlstate '75000' set message_text='Exception 2';
    end@

    commit@

    begin
    declare exit handler for sqlexception
    begin
    ROLLBACK TO SAVEPOINT sp1;
    end;
    SAVEPOINT sp1 ON ROLLBACK RETAIN CURSORS;
    insert into test values 3;
    signal sqlstate '75000' set message_text='Exception 3';
    end@

    commit@

    select * from test@

    Regards,
    Mark

    Hi,

    You are not allowed to run static DDL statement in an anonymous compound statement like this.
    You must use dynamic one instead:

    --#SET TERMINATOR @
    BEGIN
    DECLARE STMT VARCHAR(4000);
    DECLARE EXIT HANDLER FOR SQLEXCEPTION
    BEGIN
    ROLLBACK TO SAVEPOINT sp1;
    END;

    SAVEPOINT sp1 ON ROLLBACK RETAIN CURSORS;

    -- Create Tables
    SET STMT=
    '
    CREATE TABLE CONFIG (
    CONFIG BIGINT NOT NULL GENERATED BY DEFAULT AS IDENTITY,
    CLIENT_ID BIGINT NOT NULL)
    '
    ;
    PREPARE S1 FROM STMT;
    EXECUTE S1;
    signal sqlstate '75000' set message_text='Exception 3';
    END@

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Mark Barinstein@21:1/5 to Mark Barinstein on Wed Feb 21 23:45:43 2018
    On Tuesday, February 20, 2018 at 10:07:39 AM UTC+3, Mark Barinstein wrote:
    On Monday, February 19, 2018 at 3:06:03 PM UTC+3, nps.fe...@gmail.com wrote:
    Hi Mark,

    Thanks for your input.
    Your approach works but only with simple scripts, say inserts, updates etc..., but when i put a CREATE TABLE it fails.

    This is my example and the error:


    BEGIN
    DECLARE EXIT HANDLER FOR SQLEXCEPTION
    BEGIN
    ROLLBACK TO SAVEPOINT sp1;
    END;

    SAVEPOINT sp1 ON ROLLBACK RETAIN CURSORS;

    -- Create Tables
    CREATE TABLE CONFIG (
    CONFIG BIGINT NOT NULL GENERATED BY DEFAULT AS IDENTITY,
    CLIENT_ID BIGINT NOT NULL);

    signal sqlstate '75000' set message_text='Exception 3';
    END;

    Error:

    An unexpected token "<ddl-statement>" was found following "". Expected tokens may include: "".. SQLCODE=-104, SQLSTATE=42601, DRIVER=3.69.49
    An unexpected token "<ddl-statement>" was found following "". Expected tokens may include: "".. SQLCODE=-104, SQLSTATE=42601, DRIVER=3.69.49


    Any idea why?


    Cheers


    On Tuesday, February 13, 2018 at 9:02:56 AM UTC, Mark Barinstein wrote:
    Hi,

    See the example below:

    --#SET TERMINATOR @
    --create table test (i int)@
    delete from test@

    begin atomic
    insert into test values 1;
    signal sqlstate '75000' set message_text='Exception 1';
    end@

    commit@

    begin
    -- Exit handler needed for DB2 CLP - it rollbacks a failed statement automatically
    -- if you want to have an ability to commit the 1-st insert
    --declare exit handler for sqlexception begin end;
    insert into test values 2;
    signal sqlstate '75000' set message_text='Exception 2';
    end@

    commit@

    begin
    declare exit handler for sqlexception
    begin
    ROLLBACK TO SAVEPOINT sp1;
    end;
    SAVEPOINT sp1 ON ROLLBACK RETAIN CURSORS;
    insert into test values 3;
    signal sqlstate '75000' set message_text='Exception 3';
    end@

    commit@

    select * from test@

    Regards,
    Mark

    Hi,

    You are not allowed to run static DDL statement in an anonymous compound statement like this.
    You must use dynamic one instead:

    --#SET TERMINATOR @
    BEGIN
    DECLARE STMT VARCHAR(4000);
    DECLARE EXIT HANDLER FOR SQLEXCEPTION
    BEGIN
    ROLLBACK TO SAVEPOINT sp1;
    END;

    SAVEPOINT sp1 ON ROLLBACK RETAIN CURSORS;

    -- Create Tables
    SET STMT=
    '
    CREATE TABLE CONFIG (
    CONFIG BIGINT NOT NULL GENERATED BY DEFAULT AS IDENTITY,
    CLIENT_ID BIGINT NOT NULL)
    '
    ;
    PREPARE S1 FROM STMT;
    EXECUTE S1;
    signal sqlstate '75000' set message_text='Exception 3';
    END@

    Or instead of SET=...; PREPARE ...; EXECUTE ...; just:

    EXECUTE IMMEDIATE '
    CREATE TABLE CONFIG (
    CONFIG BIGINT NOT NULL GENERATED BY DEFAULT AS IDENTITY,
    CLIENT_ID BIGINT NOT NULL)
    ';

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)