0

hi im trying to insert the resultset to temporary table using this method,

this was asked before How i can put a result set from a stored procedure in a temporary table in DB2 but no one actually answer it so.

CREATE OR REPLACE PROCEDURE SCHEMANAME.SP_CALLER()
DYNAMIC RESULT SETS 1

BEGIN
DECLARE GLOBAL TEMPORARY TABLE SESSION.temp_table(
useraccountid SMALLINT,
roleid SMALLINT,
userid varchar(20),
username varchar(50),
lastlogindate TIMESTAMP,
deleted SMALLINT
) ON COMMIT PRESERVE ROWS;

P1:BEGIN

DECLARE loc_cursor RESULT_SET_LOCATOR VARYING;

CALL SCHEMANAME.PR_USERACCOUNTGETALL();


ASSOCIATE RESULT SET LOCATOR (loc_cursor) WITH PROCEDURE SCHEMANAME.PR_USERACCOUNTGETALL;
ALLOCATE cur CURSOR FOR RESULT SET loc_cursor;

--INSERT INTO #TEMPTABLE (cur);
--FETCH cur INTO TRANSACTIONCODE;
--CLOSE CUR;

Insert into session.temp_table(cur);

END P1;

END

UPDATED CODE:

I tried the snippet code that you suggest, It runs no error, But i need to return the resultset i queried from the SESSION.temp_table,

DECLARE ret CURSOR WITH RETURN FOR SELECT * FROM SESSION.temp_table where userid='JOHNDOE'; open ret;

how will I return the values from here now??

CREATE OR REPLACE PROCEDURE ITRS.SP_CALLER()
DYNAMIC RESULT SETS 1

BEGIN
DECLARE GLOBAL TEMPORARY TABLE SESSION.temp_table(
USERACCOUNTID SMALLINT,
ROLEID SMALLINT,
USERID VARCHAR(20),
USERNAME VARCHAR(50),
LASTLOGINDATE TIMESTAMP,
DELETED SMALLINT
);

P1:BEGIN

DECLARE loc_cursor RESULT_SET_LOCATOR VARYING;
DECLARE a CHAR(5) DEFAULT '00000';
DECLARE v_useraccountid SMALLINT;
DECLARE v_roleid SMALLINT;
DECLARE v_userid VARCHAR(20);
DECLARE v_username VARCHAR(50);
DECLARE v_lastlogindate TIMESTAMP;
DECLARE v_deleted SMALLINT;

DECLARE ret CURSOR WITH RETURN FOR
SELECT * FROM SESSION.temp_table where userid='JOHNDOE';
open ret;


CALL ITRS.PR_USERACCOUNTGETALL();

ASSOCIATE RESULT SET LOCATOR (loc_cursor) WITH PROCEDURE ITRS.PR_USERACCOUNTGETALL;
ALLOCATE cur CURSOR FOR RESULT SET loc_cursor;

ins_loop: LOOP
FETCH cur INTO v_useraccountid,v_roleid,v_userid,v_username,v_lastlogindate,v_deleted;
IF a <> '00000' THEN LEAVE ins_loop; END IF;
INSERT INTO SESSION.temp_table(USERACCOUNTID,ROLEID,USERID,USERNAME,LASTLOGINDATE,DELETED)
    VALUES(v_useraccountid,v_roleid,v_userid,v_username,v_lastlogindate,v_deleted);

END LOOP ins_loop;

CLOSE cur;
END P1;

END

UPDATED:

Here i tried to just insert the data on table with normal insertion via SP, so i removed the declaration of temporary table and just directly put the dumbtable name to replace the temporary table

--#SET TERMINATOR @
CREATE OR REPLACE PROCEDURE ITRS.SP_CALLER()
DYNAMIC RESULT SETS 1

BEGIN

DECLARE loc_cursor RESULT_SET_LOCATOR VARYING;
DECLARE SQLSTATE CHAR(5) DEFAULT '00000';
DECLARE v_useraccountid SMALLINT;
DECLARE v_roleid SMALLINT;
DECLARE v_userid VARCHAR(20);
DECLARE v_username VARCHAR(50);
DECLARE v_lastlogindate TIMESTAMP;
DECLARE v_deleted SMALLINT;

DECLARE ret CURSOR WITH RETURN FOR
SELECT * FROM ITRS.DUMBTABLE where USERID='JOHNDOE';


CALL ITRS.PR_USERACCOUNTGETALL();

ASSOCIATE RESULT SET LOCATOR (loc_cursor) WITH PROCEDURE ITRS.PR_USERACCOUNTGETALL;
ALLOCATE cur CURSOR FOR RESULT SET loc_cursor;

ins_loop: 
LOOP
  FETCH cur INTO v_useraccountid,v_roleid,v_userid,v_username,v_lastlogindate,v_deleted;
  IF SQLSTATE <> '00000' THEN LEAVE ins_loop; END IF;
  INSERT INTO ITRS.DUMBTABLE(USERACCOUNTID,ROLEID,USERID,USERNAME,LASTLOGINDATE,DELETED)
  VALUES(v_useraccountid,v_roleid,v_userid,v_username,v_lastlogindate,v_deleted);
  COMMIT;
END LOOP ins_loop;
CLOSE cur;
open ret;
END@
Applegate
  • 27
  • 6

1 Answers1

1

You should fetch data from the cursor in a loop as described in LOOP statement in SQL procedures, for example.

--#SET TERMINATOR @
DECLARE GLOBAL TEMPORARY TABLE SESSION.temp_table(
USERACCOUNTID SMALLINT,
ROLEID SMALLINT,
USERID VARCHAR(20),
USERNAME VARCHAR(50),
LASTLOGINDATE TIMESTAMP,
DELETED SMALLINT
) WITH REPLACE NOT LOGGED@

CREATE OR REPLACE PROCEDURE ITRS.SP_CALLER()
DYNAMIC RESULT SETS 1

BEGIN

DECLARE loc_cursor RESULT_SET_LOCATOR VARYING;
DECLARE SQLSTATE CHAR(5) DEFAULT '00000';
DECLARE v_useraccountid SMALLINT;
DECLARE v_roleid SMALLINT;
DECLARE v_userid VARCHAR(20);
DECLARE v_username VARCHAR(50);
DECLARE v_lastlogindate TIMESTAMP;
DECLARE v_deleted SMALLINT;

DECLARE ret CURSOR WITH RETURN FOR
SELECT * FROM SESSION.temp_table where userid='JOHNDOE';

DECLARE GLOBAL TEMPORARY TABLE SESSION.temp_table(
USERACCOUNTID SMALLINT,
ROLEID SMALLINT,
USERID VARCHAR(20),
USERNAME VARCHAR(50),
LASTLOGINDATE TIMESTAMP,
DELETED SMALLINT
) WITH REPLACE NOT LOGGED;

CALL ITRS.PR_USERACCOUNTGETALL();

ASSOCIATE RESULT SET LOCATOR (loc_cursor) WITH PROCEDURE ITRS.PR_USERACCOUNTGETALL;
ALLOCATE cur CURSOR FOR RESULT SET loc_cursor;

ins_loop: 
LOOP
  FETCH cur INTO v_useraccountid,v_roleid,v_userid,v_username,v_lastlogindate,v_deleted;
  IF SQLSTATE <> '00000' THEN LEAVE ins_loop; END IF;
  INSERT INTO SESSION.temp_table(USERACCOUNTID,ROLEID,USERID,USERNAME,LASTLOGINDATE,DELETED)
  VALUES(v_useraccountid,v_roleid,v_userid,v_username,v_lastlogindate,v_deleted);
END LOOP ins_loop;

CLOSE cur;
open ret;

END@

Note, that you must use some different statement separator like @ instead of the default one ;, if you use a COMPOUND SQL statement.
Do not change the SQLSTATE variable name. It's the special one. It's set almost after each statement executed automatically.
The example should work in the Db2 Command Line Processor (it understands such a directive as in the 1-st line), if you run a file containing this text.
If you use some different tool to run the statement, you must find there a place, where the default statement terminator can be changed.

Mark Barinstein
  • 11,456
  • 2
  • 8
  • 16
  • Hi Mark, I just tried this code, but it shows unexpected error. An unexpected token "SQLSTATE" was found following "DECLARE". Expected tokens may include: "".. SQLCODE=-104, SQLSTATE=42601, DRIVER=4.18.60 – Applegate Apr 12 '19 at 05:41
  • 1
    This is only a main part of the routine, not a whole code. Provide your full code to check. – Mark Barinstein Apr 12 '19 at 08:27
  • Hi Mark, i updated the post, and added my new stored procedure., Kindly check if i'm missing something., coz it doesn't return anything, – Applegate Apr 12 '19 at 08:35
  • @Applegate Check your code with my modifications. I didn't try it, but it should work... – Mark Barinstein Apr 12 '19 at 20:41
  • i tried the code you posted but session.temp_table is now undefined name, "SESSION.TEMP_TABLE" is an undefined name.. SQLCODE=-204, SQLSTATE=42704, DRIVER=4.18.60 is this a procedural?? coz if i put the declaration of the temp_table on the top most of the code, it gives me different error like An unexpected token "" was found following "". Expected tokens may include: "".. SQLCODE=-104, SQLSTATE=42601, DRIVER=4.18.60 – Applegate Apr 15 '19 at 01:43
  • @Applegate Sorry, I forgot to mention. When you declare a cursor referencing a declared global temporary table **statically** (as in the example), the definition of this table must be know in the session **before** the routine creation. So, just declare this GTT before the routine creation with the same statement as in the edited example. You don't have to do this before the routine invocation afterwards in other sessions. – Mark Barinstein Apr 15 '19 at 06:59
  • I tried to run the sql that create GTT alone, and i got this error.. A table space could not be found with a page size of at least "4096" that authorization ID "USERNAME" is authorized to use.. SQLCODE=-286, SQLSTATE=42727, DRIVER=4.18.60, have you encounter this error? I think my authorization id doesn't have a privilege to make temporary table(that deletes all rows after 1 transaction, this is just my assumption though) – Applegate Apr 15 '19 at 07:40
  • 1
    Your user is not allowed to use any *user temporary tablespaces* probably to declare GTTs there. Ask you DBA to resolve the problem. – Mark Barinstein Apr 15 '19 at 08:00
  • Thank you very much Mark for your assistance :) – Applegate Apr 15 '19 at 08:32
  • Hi Mark, As DBA said, they don't allowed me to use temporary tablespaces, so i tried to create a dumptable to insert those datarows, then i run the sql(without declaring the temporary table but as normal insertion of rows only to dumptable),but as i check the dumptable it is empty table, i assumed the resultset of external SP didn't really insert, or it already end the loop, though i cant say really coz i dont know how to actually printout where the program now runs per line. – Applegate Apr 16 '19 at 02:56