Two cursors sequence in procedure - sql

I have the following problem with a procedure:
CREATE PROCEDURE TEST()
LANGUAGE SQL
BEGIN
DECLARE V_TEST VARCHAR(100);
DECLARE V_TEST_EXT VARCHAR(100);
DECLARE SQLCODE INTEGER DEFAULT -1;
DECLARE RET_CODE INTEGER DEFAULT -2;
DECLARE LIST_CMD VARCHAR(512);
DECLARE LIST_CMD_EXT VARCHAR(512);
DECLARE CUR_TEST CURSOR WITH RETURN FOR LIST_STMT;
DECLARE CUR_TEST_EXT CURSOR WITH RETURN FOR LIST_EXT_STMT;
DECLARE CONTINUE HANDLER FOR SQLEXECPTION SET RET_CODE = SQLCODE;
SET LIST_CMD = 'SELECT TEST FROM TESTTAB';
PREPARE LIST_STMT FROM LIST_CMD;
OPEN CUR_TEST;
FETCH CUR_TEST INTO V_TEST;
WHILE (RET_CODE <> 100) DO
FETCH CUR_TEST INTO V_TEST;
END WHILE;
CLOSE CUR_TEST;
SET LIST_CMD_EXT = 'SELECT TEST FROM TESTTAB';
PREPARE LIST_STMT_EXT FROM LIST_CMD_EXT;
OPEN CUR_TEST_EXT;
FETCH CUR_TEST_EXT INTO V_TEST_EXT;
WHILE (RET_CODE <> 100) DO
FETCH CUR_TEST_EXT INTO V_TEST_EXT;
END WHILE;
CLOSE CUR_TEST_EXT;
END;
The problem I am having is that the procedure does the first cursor loop but ignores the second one. I tried adding BEGIN and END to each loop but that didn't help as well.
I am running DB2 v10.5 Windows. I need this to work as a procedure. Is there any way to make the procedure run both loops?
Thank you for your help.-

You don't reset the RET_CODE variable before processing the 2-nd cursor.
Use something like this:
SET RET_CODE = 0;
OPEN CUR_TEST_EXT;
...
BTW, don't declare a cursor using 'WITH RETURN' clause if you process this cursor inside the procedure.

Related

error 1178: syntax error in a stored procedure in mariadb columnstore

I try to produce a stored procedure that allows me to update many tables in my database but when I try to execute it with a columnstore engine, i get an error of procedure syntax not supported. I have looked for it in the web but do not manage to find where is the issue. If you have an idea, I let you the procedure here.
DELIMITER $$
CREATE PROCEDURE update_sp_aggregated()
BEGIN
DECLARE finished INTEGER DEFAULT 0;
DECLARE tableName varchar(255) DEFAULT "";
DECLARE cursor_update
CURSOR FOR
SELECT table_name FROM INFORMATION_SCHEMA.TABLES WHERE table_name like 'sp_aggr%' ;
OPEN cursor_update;
updateAggregated: LOOP
FETCH cursor_update into tableName;
IF finished = 1 THEN
LEAVE updateAggregated;
END IF;
SET #sql = CONCAT('ALTER TABLE ', tableName, ' ADD COLUMN col2 varchar(5)');
PREPARE stmt FROM #sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
SET #sql = CONCAT('UPDATE ', tableName, ' SET col2= LEFT(col1, 1)');
PREPARE stmt FROM #sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
END LOOP updateAggregated;
CLOSE cursor_update;
END $$
-- declare NOT FOUND handler
DECLARE CONTINUE HANDLER
FOR NOT FOUND SET finished = 1;
DELIMITER ;
CALL update_sp_aggregated();
Finally found, so as tell in my comment, the issue was the update command was not allowed.
to solve it, you need to change the variable infinidb_vtable_mode by setting it to 0.
All is described here
and here

DB2 stored procedure FETCH doesn't move to the end of cursor

Here is my stored procedure:
CREATE PROCEDURE PROC1()
LANGUAGE SQL
BEGIN
DECLARE EOF INT DEFAULT 0;
DECLARE SQLCODE INT DEFAULT 0;
DECLARE var_MYID INT;
DECLARE PCURSOR CURSOR FOR SELECT MYID FROM MYTABLE
OPEN PCURSOR;
WHILE EOF = 0 DO
FETCH FROM PCURSOR INTO var_MYID;
IF SQLCODE = 100 THEN
SET EOF = 1;
ELSE
-- nested cursor goes here
END IF;
END WHILE;
CLOSE PCURSOR;
END
SQLCODE = 100 newer happens (it's always 0 when I debug). So it becomes infinite loop. I'm not using
DECLARE CONTINUE HANDLER FOR NOT FOUND SET EOF = 1;
because I'm going to use another nested cursor.

Reset cursor's position to the beginng each time the script is being launched

I'm currently studying T-SQL procedures and cursors, but I've faced the problem recently. How can I reset to the beginnig position of the cursor that was returned from the procedure (after fetching all the data from it)? I have a cursor in the following context:
CREATE PROCEDURE dbo.my_procedure
#curs CURSOR VARYING OUTPUT
AS
SET #curs = CURSOR
SCROLL FOR
select book_name, author_lastname
from dbo.books;
OPEN #curs;
go
declare #tmp_curs cursor;
declare #val_1 varchar(35), #val_2 varchar(35);
EXEC dbo.my_procedure #tmp_curs output;
WHILE (##FETCH_STATUS = 0)
BEGIN
print #val_1 + ' ' + #val_2 + ';'
FETCH NEXT FROM #tmp_curs
INTO #val_1, #val_2;
END;
CLOSE #tmp_curs;
DEALLOCATE #tmp_curs;
go
When I run this script for the first time I get the result I need (entries from the cursor). But when I run this next time I only get result as
"(100 row(s) affected)"
And not the actual entries, so I have to restart Server Management Studio.
I have tried working with
##FETCH_STATUS,
reexecuting procedure, and
closing-opening cursors but nothing seems to work for me. How can I get the same result (entries from cursor) each time I run this script?
If I understand you correctly you can use FETCH FIRST FROM:
DECLARE #tmp_curs cursor;
DECLARE #val_1 varchar(35), #val_2 varchar(35);
-- first run
EXEC dbo.my_procedure #tmp_curs output;
FETCH FIRST FROM #tmp_curs INTO #val_1, #val_2;
WHILE (##FETCH_STATUS = 0)
BEGIN
INSERT INTO books2 VALUES (#val_1, #val_2);
FETCH NEXT FROM #tmp_curs
INTO #val_1, #val_2;
END;
CLOSE #tmp_curs;
DEALLOCATE #tmp_curs;
-- second run
EXEC dbo.my_procedure #tmp_curs output;
FETCH FIRST FROM #tmp_curs INTO #val_1, #val_2;
WHILE (##FETCH_STATUS = 0)
BEGIN
INSERT INTO books2 VALUES (#val_1, #val_2);
FETCH NEXT FROM #tmp_curs
INTO #val_1, #val_2;
END;
CLOSE #tmp_curs;
DEALLOCATE #tmp_curs;
-- checking
SELECT *
FROM books2;
SqlFiddleDemo

DB2 Declare/Set Variable in Stored Procedure

I can't get this stored procedure to compile, I simply want to declare and set one variable that will be used in the proc. NOTE: shipNo is the only incoming parameter, and is VARCHAR(32).
P1: BEGIN
DECLARE #likeShipNo VARCHAR(32);
SET likeShipNo = '%' || shipNo || '%';
DECLARE cursor1 CURSOR WITH RETURN FOR
SELECT ADV_SHIP_NOTICE_NO,
VNDR_ID,
LOC,
CARR_CD,
CARR_PRO_NO,
BL_NO,
SHIP_EQUIP_ID,
TS_LOAD
FROM TRITS
WHERE ADV_SHIP_NOTICE_NO LIKE(#likeShipNo);
OPEN cursor1;
END P1
The variables in DB2 doesn't need the # like in MSSQL. Also, when you return a cursor, you need to add the sentence RESULT SET 1 before begin and add the WITH RETURN TO CLIENT to the cursor that you want to return. The procedure should look like this:
CREATE BEGIN MYSCHEMA.MYPROC (
IN shipNo VARCHAR(30) )
BEGIN
DECLARE likeShipNo VARCHAR(32);
SET likeShipNo = '%' || shipNo || '%';
DECLARE cursor1 CURSOR WITH RETURN TO CLIENT FOR
SELECT
ADV_SHIP_NOTICE_NO,
VNDR_ID,
LOC,
CARR_CD,
CARR_PRO_NO,
BL_NO,
SHIP_EQUIP_ID,
TS_LOAD
FROM
TRITS
WHERE
ADV_SHIP_NOTICE_NO LIKE likeShipNo;
OPEN cursor1;
END;

looping inside stored procedures

I am writing a trigger in DB2. Inside that i wanted to use a loop.
This is to iterate through a set of values returned from a select statement.
How can this be done?
Anybody please share a tutorial or link which explains this.
Also is it ok to have nested loop?
You can use a cursor in your trigger:
http://en.wikipedia.org/wiki/Cursor_%28databases%29
A simple cursor example looks like this:
DECLARE SQLSTATE CHAR(5) DEFAULT '00000';
DECLARE p_sum INTEGER;
SET p_sum = 0;
DECLARE p_sal INTEGER;
DECLARE c CURSOR FOR SELECT SALARY FROM EMPLOYEE;
OPEN c;
FETCH FROM c INTO p_sal;
WHILE(SQLSTATE = '00000') DO
SET p_sum = p_sum + p_sal;
FETCH FROM c INTO p_sal;
END WHILE;
CLOSE c;