【问题标题】:How to insert cursor/resultset that produced by stored procedure to temporary table in db2如何将存储过程生成的游标/结果集插入到 db2 中的临时表中
【发布时间】:2019-09-02 18:12:26
【问题描述】:

您好,我正在尝试使用此方法将结果集插入临时表,

How i can put a result set from a stored procedure in a temporary table in DB2 之前有人问过这个问题,但实际上没有人这样回答。

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

更新代码:

我尝试了你建议的sn-p代码,它运行没有错误,但我需要返回我从SESSION.temp_table查询的结果集,

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

我现在如何从这里返回值??

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

更新:

这里我尝试通过SP将数据插入到正常插入的表中,所以我删除了临时表的声明,直接将哑表名称替换为临时表

--#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@

【问题讨论】:

    标签: stored-procedures db2 resultset


    【解决方案1】:

    例如,您应该按照LOOP statement in SQL procedures 中所述的循环从游标中获取数据。

    --#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@
    

    请注意,如果您使用 COMPOUND SQL 语句,则必须使用一些不同的语句分隔符,例如 @ 而不是默认的 ;
    不要更改SQLSTATE 变量名。这是特别的。它几乎在每条语句自动执行后设置。
    如果您运行包含此文本的文件,该示例应该可以在 Db2 命令行处理器中运行(它可以理解第一行中的指令)。
    如果你使用一些不同的工具来运行语句,你必须找到一个可以更改默认语句终止符的地方。

    【讨论】:

    • 嗨,马克,我刚刚尝试了这段代码,但它显示了意外错误。在“DECLARE”之后发现了意外的标记“SQLSTATE”。预期的标记可能包括:“”.. SQLCODE=-104, SQLSTATE=42601, DRIVER=4.18.60
    • 这只是例程的主要部分,而不是完整的代码。提供您的完整代码以进行检查。
    • 嗨,马克,我更新了帖子,并添加了我的新存储过程。请检​​查我是否遗漏了什么。因为它没有返回任何内容,
    • @Applegate 用我的修改检查你的代码。我没有尝试过,但它应该可以工作......
    • 不允许您的用户使用任何可能在此处声明 GTT 的 用户临时表空间。请 DBA 解决问题。
    猜你喜欢
    • 2011-07-08
    • 2018-11-16
    • 2021-01-10
    • 1970-01-01
    • 2018-07-05
    • 1970-01-01
    • 2020-01-26
    • 2020-12-05
    相关资源
    最近更新 更多