【问题标题】:Store Procedure compiling but value are not getting updated or inserted存储过程编译但值没有得到更新或插入
【发布时间】:2021-05-06 13:02:01
【问题描述】:

我在 Db2 服务器平台 - LUW 中创建了以下存储过程,版本为 v10.1.0.6。存储过程创建得非常好。

CREATE OR REPLACE PROCEDURE TAS_TEST
(
    IN I_LOGIN_ID VARCHAR(20),
    IN I_NAME      VARCHAR(100),
    IN I_C_NAME    VARCHAR(100),
    IN I_USER      VARCHAR(20),
    IN I_DEBUG     SMALLINT DEFAULT 0
)
MODIFIES SQL DATA
LANGUAGE SQL

BEGIN

DECLARE V_TOKEN_EXPIRY_DATE TIMESTAMP;
DECLARE V_TOKEN VARCHAR(36);

SET I_LOGIN_ID = TRIM(I_LOGIN_ID);

IF I_LOGIN_ID IS NULL THEN
    SIGNAL SQLSTATE VALUE '20000'
    SET MESSAGE_TEXT = 'LOGIN ID IS MUST:';
END IF;
IF I_NAME IS NULL THEN
    SIGNAL SQLSTATE VALUE '20000'
    SET MESSAGE_TEXT = 'NAME IS MUST:';
END IF;
IF I_C_NAME IS NULL THEN
    SIGNAL SQLSTATE VALUE '20000'
    SET MESSAGE_TEXT = 'C_NAME IS MUST:';
END IF;
IF I_USER IS NULL THEN
    SIGNAL SQLSTATE VALUE '20000'
    SET MESSAGE_TEXT = 'USER IS MUST:';
END IF;


MERGE INTO TOKEN_DETAILS AS TD
USING(
    SELECT
        I_LOGIN_ID,
        I_TOKEN,
        I_NAME,
        I_C_NAME,
        I_TOKEN_EXPIRY_DATE,
    FROM TOKEN_DETAILS
) AS TEMP
ON(TD.I_LOGIN_ID = TEMP.I_LOGIN_ID)
WHEN MATCHED AND TEMP.I_TOKEN IS NOT NULL THEN
    UPDATE
    SET
        I_TOKEN = V_TOKEN,
        I_TOKEN_EXPIRY_DATE = V_TOKEN_EXPIRY_DATE
    WHEN NOT MATCHED THEN
    
    INSERT INTO TOKEN_DETAILS(
        I_LOGIN_ID,
        I_TOKEN,
        I_NAME,
        I_C_NAME,
        I_TOKEN_EXPIRY_DATE,
        I_CREATED_DATE,
        I_CREATED_BY
    )VALUES(
        I_LOGIN_ID,
        V_TOKEN,
        I_NAME,
        I_C_NAME,
        V_TOKEN_EXPIRY_DATE,
        CURRENT_TIMESTAMP,
        I_USER
    );

    SELECT I_TOKEN "TOKEN" INTO V_TOKEN FROM TOKEN_DETAILS;
    SELECT I_TOKEN_EXPIRY_DATE "TOKEN_EXPIRY_DATE" INTO V_TOKEN_EXPIRY_DATE FROM TOKEN_DETAILS;
END;

GRANT EXECUTE TAS_TEST TO ADMIN;

但是,在调用/执行存储过程时,它不会更新或插入表中的值

CALL TAS_TEST('testuser','service','component','testuser',0);

有人可以告诉我我可能错在哪里。

【问题讨论】:

  • 最后两行没有意义。你可以从中得到任何结果,不一定是最近合并的行
  • 多个错误。在将它们用于更新/插入之前,您没有设置 V_TOKEN 或 V_TOKEN_EXPIRY 日期。您不会增加更新的时间戳。您在合并的源表上缺少 where 子句(大概 where 子句应该基于输入参数),以及其他错误......

标签: sql database db2 db2-luw


【解决方案1】:

多个问题...
您使用名称与表列名称相同的参数。如果您不限定它们,那么您必须知道 Db2 使用的规则来确定它是列、变量还是参数。
References to SQL parameters, SQL variables, and global variables:

应该明确限定相同的名称。排位赛 name 明确表示名称是否引用了一个列,SQL 变量、SQL 参数、行变量字段或全局变量。 如果 名称不合格,或合格但仍模棱两可, 以下规则描述名称是否引用列、SQL 变量、SQL 参数或全局变量

  • 如果 SQL 例程主体中指定的表和视图在创建例程时存在,则首先将该名称作为列名进行检查。如果未作为列找到,则将其作为复合语句中的 SQL 变量进行检查,然后作为 SQL 参数进行检查,最后作为全局变量进行检查。

回到你的例子,尤其是下面的代码:

MERGE INTO TOKEN_DETAILS AS TD
USING(
    SELECT
        I_LOGIN_ID,
        I_TOKEN,
        I_NAME,
        I_C_NAME,
        I_TOKEN_EXPIRY_DATE,
    FROM TOKEN_DETAILS
) AS TEMP
ON (TD.I_LOGIN_ID = TEMP.I_LOGIN_ID)
WHEN MATCHED AND TEMP.I_TOKEN IS NOT NULL THEN
UPDATE ...

您合并到同一个表中,并通过同一 I_LOGIN_ID 表列比较每一行。 TOKEN_DETAILS 的每一行都匹配 ON (TD.I_LOGIN_ID = TEMP.I_LOGIN_ID)(除非表为空)。 UPDATE 仅适用于 I_TOKENIS NOT NULL 将值设置为 NULL 的行,因为 V_TOKEN 变量未在 MERGE 之前初始化。

如果TOKEN_DETAILS 包含多于 1 行,您最后的 SELECT INTO 语句将失败。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-30
    • 2017-12-02
    • 2019-06-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多