Hi i'm creating a database with DB2. I use IBM Data Client. I want to use try catch into my stored procedure but it seems that are not supported by DB2, can any one help me? I need to handle sql errors and to return its. How can i do that?
DB2 LUW supports exception handlers (continue handlers, or exit handlers) for SQL PL procedures. Look in the DB2 Knowledge Center for your version for all the details. You can use them alongside conditions. You can have multiple handlers if you need specific processing. There are plenty of sample SQL PL procedures in both the Knowledge Center and in the DB2 LUW installed product directories.
CREATE OR REPLACE PROCEDURE sp_Applicazione_Aggiorna
(
IN #VAR1 INT,
IN #VAR2 INT,
IN #VAR3 VARCHAR(16),
OUT #ReturnCode INTEGER,
)
LANGUAGE SQL
P1: BEGIN
DECLARE SQLCODE INTEGER DEFAULT 0;
DECLARE CONTINUE HANDLER FOR SQLEXCEPTION, SQLWARNING, NOT FOUND
SET #ReturnCode = SQLCODE;
IF not exists (select VAR1 from DB.TABLEA where VAR1 = #VAR1)
THEN
set #ReturnCode = 3011;
ELSE
UPDATE DB.TABLEA SET
VAR2=#VAR2,
VAR3=#VAR3
WHERE VAR1=#VAR1;
END IF;
END P1
Related
I am trying to call a external stored procedure from Sql stored procedure by passing two parameters. one of the parameters is expected to return back with a string value, which when arrives I need to stop the data to be committed in any file.
To explain the situation - SP1 (SQL stored procedure) will call SP2 (External stored procedure), which will call RPGLE program PGM1, which will call another RPGLE program PGM2.
Now I am tasked to handle commitment control of File1 and File 2 used in PGM2 from SP1. If at any point File1 is updated and File2 gives an error while updating any record, data from File 1 should also be rolled back. but this rollback should happen in SP1.
So far I have tried to split this issue in two parts-
PARTA - How to Call External stored procedure from SQL stored procedure.
PARTB - How to handle commitment in SQL stored procedure in essence, if PGM2 gives back error data should be rolled back.
Below is the piece of code so far I have tried. But have no luck.
CREATE OR REPLACE PROCEDURE MYLIB.SP1 (
IN PRINPUT CHAR(1200) ,
INOUT PRERR CHAR(50) )
SPECIFIC MYLIB.SP1
BEGIN
DECLARE SQLSTATE CHAR(5) DEFAULT ' ';
DECLARE SQLCODE INTEGER DEFAULT 0;
CALL MYLIB.SP2(PRINPUT, PRERR);
IF SQLCODE = 0 THEN
COMMIT;
ENDIF;
END
Any suggestion/Guidance is appreciated.
Try this my friend:
On SP1
BEGIN
DECLARE SQLSTATE CHAR(5) DEFAULT ' ';
DECLARE SQLCODE INTEGER DEFAULT 0;
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
CALL MYLIB.SP2(PRINPUT, PRERR);
IF SQLCODE = 0 THEN
COMMIT;
ELSE
ROLLBACK;
ENDIF;
END
Answers:
PARTA: If the Ext Stored Proc exists, the way you're calling it, it's correct.
PARTB: The set transaction scopes all the rows changed from the moment is issued, to the execution of commit or rollback. Remember this, every SQL Stored proc runs on *caller actgrp, so, you need to check if your RPG program runs on *caller too.
Finally, last time I tested, dinos still walked the earth, the commit on SQL Stored Proc scoped the changes made with a RPG program called within, but the RPG STRCMTCTL doesn't get the changes made on SQL Stored Proc called within the RPG.
Have fun!
statements-set-transaction
control-example-using-transaction-logging-file-start-application
definition-example-jobs-commitment-definitions
Thank you #Jairo, I got it working.
Your solution was correct and it worked, only challenge was the SP2 didn't have any SQL statements which was causing issue, I converted the statements in SP2 to SQL statements and it worked completely fine.
I've seen in the help guides that you cannot use a call statement in a teradata dynamic sql statement without output parameter.
I assume this implies I can, If the proc has an output parameter.
has anyone done this?
Scenario -
I have a table that at some point I'll expand out in terms of fields for logic on when things should run, and this table is managed elsewhere -
CREATE TABLE DB.SP_Test
(
ProcName VARCHAR(250)
,ProcRun VARCHAR(1)
);
now I added chrTest as an output however, I am still getting an error on run (no compile error)
The error :-
SQL_State SQL_Exception
T7689 Invalid dynamic SQL statement.
REPLACE PROCEDURE DB.Test_Control (OUT chrTest VARCHAR(250) )
SQL SECURITY INVOKER
LMain:
BEGIN
DECLARE sqlProcRun VARCHAR(20000);
DECLARE CONTINUE HANDLER
FOR SqlException
BEGIN
-----------------------------------------------------------------------------
DECLARE strExceptionText VARCHAR(250);
GET DIAGNOSTICS EXCEPTION 1 strExceptionText = Message_Text;
INSERT INTO DB.PROC_ERROR VALUES
(
'Test_Control'
,:SqlState
,strExceptionText
,Current_Timestamp
)
;
END;
-----------------------------------------------------------------------------
SET sqlProcRun ='';
L0:
FOR procs_run_cursor AS select_list
CURSOR FOR
SELECT Trim(ProcName) AS ProcName
FROM DB.SP_Test
DO
/*creating a lost of call statements to run*/
SET sqlProcRun = sqlProcRun ||'CALL DB.'||procs_run_cursor.ProcName|| '();';
END FOR L0;
EXECUTE IMMEDIATE sqlProcRun;
END;
Enviroment:
DB2 Version 11.1,
OS - Linux
How to get the result table of stored procedure into a temp table?
The table and the result have the same table configuration (firstColumn int, secondColumn nvarchar(255))
I'm assuming your stored procedure returns an open cursor, so you want to consume that cursor, inserting its contents into a session table (declared global temporary table) on Db2-LUW.
In addition to fetch and insert statements, you need to understand the following statements:
associate result set locator ... with procedure ...
allocate ... cursor for result set ...
Here is a deliberately artificial example of a nested stored procedure, which shows fetching a result-set from a nested procedure into a session table. The purpose is to show how the syntax works, rather than to do anything useful with data (as the net effect can be equally met by a simple catalog query in this case). This example can be run at the Db2 command-line (for example at the bash shell, after you connected to a database with appropriate permissions):
update command options using s on ;
--#SET TERMINATOR #
create or replace procedure alltabs
dynamic result sets 1
language sql
specific alltabs
begin
declare v_cur cursor with return to caller for select tabschema,tabname,type from syscat.tables ;
open v_cur;
end#
declare global temporary table session.thetables(tabschema varchar(128), tabname varchar(128))
not logged with replace on commit preserve rows #
create or replace procedure populate_dgtt()
language sql
specific populate_dgtt
begin
declare v_rs result_set_locator varying;
declare v_tabschema varchar(128);
declare v_tabname varchar(128);
declare v_type char(1);
declare sqlstate char(5) default '00000';
call alltabs;
associate result set locator (v_rs) with procedure alltabs;
allocate v_rscur cursor for result set v_rs;
fetch from v_rscur into v_tabschema, v_tabname, v_type;
while ( sqlstate = '00000') do
if v_type='V' and v_tabschema='SYSSTAT'
then
insert into session.thetables(tabschema,tabname) values (v_tabschema, v_tabname);
end if;
fetch from v_rscur into v_tabschema, v_tabname, v_type;
end while;
return;
end#
call populate_dgtt()#
select rtrim(Tabschema)||'.'||rtrim(tabname) from session.thetables #
Trying to create the stored procedure in redshift aginity workbench but it through an error like 'unterminated dollar-quoted string at or near "$$
'
In amazon, they already gave the solution for this
https://docs.aws.amazon.com/redshift/latest/dg/stored-procedure-create.html
particular client tool only supported to create the stored procedure.
I want to conform aginity don't have the option to create this?
and
Which is the best tool to create stored-procedure?
CREATE OR REPLACE PROCEDURE staging.test_sp1(f1 int, f2 varchar)
AS $$
BEGIN
RAISE INFO 'f1 = %, f2 = %', f1, f2;
END;
$$ LANGUAGE plpgsql;
You can create RedShift stored procedures in Aginity Pro by using Run Batch. Full support will be in the 9/16 release.
Aginity need to update their tool to pass the dollar quoted procedure body to Redshift correctly. I note that Aginity is able to execute the procedure with CALL staging.test_sp1().
Some other tools have already been updated to allow creation and you can always use psql to create the procedure.
I am trying to retrieve multiple rows from table using stored procedure and it doesn't work for me. My stored procedure is as follows,
CREATE OR REPLACE PROCEDURE E_Enquiry
(IN SourceQueue1 VARCHAR(30) ) LANGUAGE SQL
BEGIN
DECLARE C1 CURSOR FOR
select CreationTime
from ms.Exception_Message
where SourceQueue = SourceQueue1;
open c1;
END;
I am trying to call the stored procedure from Mule Anypoint Studio using the Database connector and have seen the result as null when I print the payload with a logger. If I try to modify the query as it returns a single row it works (without using cursor).
Please help to resolve this. Thanks.
What platform and version of DB2?
Try the adding
DYNAMIC RESULT SETS 1
WITH RETURN TO CLIENT
Like so:
CREATE OR REPLACE PROCEDURE E_Enquiry
(IN SourceQueue1 VARCHAR(30) )
LANGUAGE SQL
DYNAMIC RESULT SETS 1
BEGIN
DECLARE C1 CURSOR WITH RETURN TO CLIENT FOR
select CreationTime
from ms.Exception_Message
where SourceQueue = SourceQueue1;
open c1;
END;