【问题标题】:How to use SET OPTION within a DB2 stored procedure如何在 DB2 存储过程中使用 SET OPTION
【发布时间】:2021-06-01 01:07:12
【问题描述】:

我读到(并尝试过)我不能在 DB2 存储过程中使用 WITH UR。有人告诉我,我可以使用 SET OPTION 来达到同样的效果。但是,当我在我的存储过程中实现它时,它无法编译(我在它的位置移动了同样的错误)。我的问题是:

  • 我真的不能在过程中的 SELECT 语句之后使用 WITH UR 吗?
  • 为什么我的存储过程无法编译并出现以下错误 留言?

这是我的代码的简化版本:

    CREATE OR REPLACE PROCEDURE MySchema.MySampleProcedure()
        DYNAMIC RESULT SETS 1 
        LANGUAGE SQL 
        SET OPTION COMMIT=*CHG 
        
        BEGIN
             DECLARE GLOBAL TEMPORARY TABLE TEMP_TABLE AS (
             SELECT 'testValue' as "Col Name"
             ) WITH DATA
        

        BEGIN
             DECLARE  exitCursor CURSOR WITH RETURN FOR
             SELECT *
             FROM SESSION.TEMP_TABLE;
             OPEN exitCursor;
        END;

        END 
        @

Error Message: 

SQL0104N 发现意外的标记“SET OPTION COMMIT=*CHG” 遵循“语言 SQL”

这是我使用 WITH UR

时的代码/错误
CREATE OR REPLACE PROCEDURE MySchema.MySampleProcedure()

    LANGUAGE SQL 
    DYNAMIC RESULT SETS 1 

--#SET TERMINATOR @
BEGIN

    DECLARE GLOBAL TEMPORARY TABLE TEMP_TABLE AS (
        SELECT UTI AS "Trade ID" FROM XYZ WITH UR
        ) WITH DATA;

    BEGIN
        DECLARE  exitCursor CURSOR WITH RETURN FOR
            SELECT *
            FROM SESSION.TEMP_TABLE;
        OPEN exitCursor;
    END;

END
@

第 9 行是 DECLARE GLOBAL TEMPORARY ... 所在的位置

DB21034E 该命令被作为 SQL 语句处理,因为它是 不是有效的命令行处理器命令。在 SQL 处理期间 返回:SQL0109N 未处理语句或命令,因为 以下子句在其所在的上下文中不受支持 使用:“隔离使用并保持”。行号=9。 SQLSTATE=42601

【问题讨论】:

  • Db2 的哪个平台(i series/AS400、Z/OS 或 Linux/Unix/Windows?在寻求 Db2 方面的帮助时,您必须始终提供此信息。
  • Linux/Windows (DB2 LUW 8.x)

标签: sql stored-procedures db2 db2-luw isolation-level


【解决方案1】:

如果您的 Db2 服务器在 Linux/Unix/Windows (Db2-LUW) 上运行,则不存在 SET OPTION COMMIT=*CHG 这样的语句,因此 Db2 将针对该无效语法抛出异常。

请务必为您的 Db2 平台和您的 Db2 版本使用匹配的 Db2 知识中心。不要将 Db2-Z/OS 文档用于 Db2-LUW 开发。语法和功能因平台和版本而异。

Db2-LUW SQL PL 过程可以在其内部查询中使用with ur,如果您遇到错误,则说明其他问题。但是,您必须以正确的语法使用with ur,即在支持此子句的语句中。对于您的示例,您会收到错误消息,因为该子句在所描述的上下文中似乎无效。您可以通过其他方式实现所需的结果,其中之一是在声明之外的单独语句中填充表格(例如 insert into session.temp_table("Trade ID") select uti from xyz with ur; ),其他方式也是可能的。

使用在线 Db2 Knowledge Cenbtre 文档的一个原因是它包含示例程序,包括示例 SQL PL 过程,这些示例程序也可以在 DB2-LUW 服务器的 sample 目录中以源代码形式提供,此外在 github 上可用。学习这些并让它们为你工作是明智的。

【讨论】:

  • 这将解释为什么 SET OPTION 无法编译。我再次在 SELECT 语句的末尾添加了 WITH UR 我收到错误并指向声明临时表的行:[SQL0109N 未处理语句或命令,因为在使用它的上下文中不支持以下子句:“与隔离使用并保持”。]
  • 在上下文中没有看到 exact full 语句,我假设您使用不正确。
  • 我在问题中使用 WITH UR 时添加了完整的语句和错误。如果您能看看@Mao,将不胜感激。
  • 我可以使用 ISOLATION LEVEL UR 作为存储过程最顶部的一个选项来实现相同的效果,对吧?参考:ibm.com/support/knowledgecenter/SSEPEK_11.0.0/sqlref/src/tpc/…
  • DB2 v11.1.4.5 是确切的版本。 8.x 是 dbeaver 中使用的驱动程序(我想念那个)。
【解决方案2】:

Specifying the isolation level:

对于静态 SQL:

  • 如果在语句中指定了隔离子句,则使用该子句的值。
  • 如果语句中没有指定隔离子句,则使用包绑定到数据库时为包指定的隔离级别。

您需要将例程包与 UR 绑定,因为您的 DECLARE GTT 语句是静态的。在CREATE OR REPLACE 之前在同一会话中使用以下内容:

CALL SET_ROUTINE_OPTS('ISOLATION UR')

P.S.:如果您不仅想在同一会话中运行例程 1 次而不会出错,请使用 DECLARE 的附加 WITH REPLACE 选项。

【讨论】:

  • 只是为了确认一下,在编译存储过程之前,这个调用只需要一次。用户可以直接调用存储过程而不用担心隔离级别?
  • 是的。将此视为例程创建的环境设置。例程中的所有静态语句都将使用此隔离级别,如果它们没有在语句级别使用显式隔离级别规范。
  • 谢谢@Mark!如果一切顺利,我将测试此解决方案并接受此答案。
猜你喜欢
  • 1970-01-01
  • 2019-05-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-03-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多