【问题标题】:DB2 Select Statement error after for loop in stored procedure存储过程中 for 循环后的 DB2 Select Statement 错误
【发布时间】:2018-07-16 10:00:50
【问题描述】:

我编写了一个存储过程,它使用 for 循环来执行对视图列表的查询。它为 for 循环中的每个视图生成一个动态 sql 语句,然后执行它,将输出插入到已声明的临时表中。

for 循环运行良好,运行时没有错误,但是如果我在 END FOR; 之后添加一个 select 语句;要从临时表中获取最终输出,我会收到以下错误。请问有人有什么想法吗?

Error 16/07/2018 10:43:41 0:00:00.007 DB2 Database Error: ERROR [42601] [IBM][DB2/AIX64] SQL0104N An unexpected token "select *" was found following "1; END FOR; ". Expected tokens may include: "<call>". LINE NUMBER=31. SQLSTATE=42601

SQL 代码:

BEGIN
 DECLARE SQLTEXT varchar(500);
 DECLARE GLOBAL TEMPORARY TABLE SESSION.AS_USAGE_RESULTS(
  temp table columns
 );

 FOR v as cur1 cursor for
   select distinct viewname,viewschema
   from syscat.VIEWS
  DO

  SET SQLTEXT = 'Dynamic Insert into temp table here' 

  PREPARE s1 FROM SQLTEXT;
  EXECUTE s1;
 END FOR;

 select *
   from SESSION.AS_USAGE_RESULTS;

 DROP TABLE SESSION.AS_USAGE_RESULTS;
END

【问题讨论】:

    标签: sql db2


    【解决方案1】:

    您的错误是,如果您希望从 session.as_usage_results 返回结果集,则必须为其选择声明一个游标,然后打开该游标然后结束存储过程。这是一个常见问题解答。 IBM Db2 Server SAMPLES 目录和 Db2 知识中心中有示例。

    在存储过程中,您可以使用 SELECT ... INTO,或者在游标中使用 select,或者使用 SELECT 作为 SET 语句的一部分。

    您不应在过程中删除会话表,以防在删除表之前不会使用结果集。要么将会话表放到别处,要么使用替代设计。

    在您的示例中,您不需要光标 cur1,所以下面我展示了一个高跷的人工示例,说明您可能的意思。这是人为的,因为您可以看到会话表对于此示例也是多余的,但它显示了游标对结果集的使用。

    --#SET TERMINATOR @
    
    create or replace procedure dynproc1
    language sql
    specific dynproc1
    dynamic result sets 1
    BEGIN
    
        DECLARE v_sqltext varchar(2000);
        DECLARE c1 cursor with return to client for s1;
        DECLARE GLOBAL TEMPORARY TABLE SESSION.AS_USAGE_RESULTS ( viewname varchar(128), viewschema varchar(128) );
    
        insert into session.as_usage_results(viewname, viewschema) select viewname, viewschema from syscat.views;
    
        set v_sqltext = 'select * from session.as_usage_results';
    
        prepare s1 from v_sqltext;
    
        open c1;
    END
    @
    

    【讨论】:

    • 非常感谢,经过多年的 SQL Server,我是 Db2 的新手。我找到了您提到的一些示例,并且在 END FOR 之后添加了 DECLARE CURSOR / OPEN CURSOR 块;但我仍然得到一个错误。非常感谢您的回答以及您可能有的任何进一步的想法! “SQL0104N 在“”之后发现了意外的标记“”。预期的标记可能包括:“”” END FOR;声明 c1 CURSOR WITH RETURN TO CALLER FOR select LOGIN_ID,APPL_NAME,SNAPSHOT_DATE,View_Name from SESSION.AS_USAGE_RESULTS;打开 c1;
    • 没关系,我发现 DB2 对存储过程中声明事物的顺序很敏感。将我的光标声明移到顶部已解决此错误。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-08-28
    • 2023-04-10
    • 1970-01-01
    • 1970-01-01
    • 2013-02-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多