当前位置: 首页 > 知识库问答 >
问题:

意外的令牌“SELECT”SQL代码=-104,SQLSTATE=42601,DRIVER=3.69.66

孟思远
2023-03-14

我有一个存储过程,需要将它从Sybase SQL更改为DB2 SQL。下面的代码是针对Sybase SQL的。

CREATE PROC TAS_TEST
(
    @LOGIN_ID VARCHAR(20),
    @NAME     VARCHAR(100),
    @C_NAME   VARCHAR(100),
    @USER     VARCHAR(20),
    @DEBUG    BIT_FLAG=0
)
AS
BEGIN

    DECLARE @TOKEN_EXPIRY_DATE DATETIME,
        @TOKEN VARCHAR(36),
        @ERR INT,
        @ERROR_MSG VARCHAR(200)
        
    SET @LOGIN_ID = LTRIM(RTRIM(@LOGIN_ID))
    
    IF @LOGIN_ID IS NULL
    BEGIN
        RAISEERROR 20000 'LOGIN ID IS MUST:[%1!]',@LOGIN_ID
        RETURN -1
    END
    IF @NAME IS NULL
    BEGIN
        RAISEERROR 20000 'NAME IS MUST:[%1!]',@NAME
        RETURN -1
    END
    IF @C_NAME IS NULL
    BEGIN
        RAISEERROR 20000 'C_NAME IS MUST:[%1!]',@C_NAME
        RETURN -1
    END
    IF @USER IS NULL
    BEGIN
        RAISEERROR 20000 'USER IS MUST:[%1!]',@USER
        RETURN -1
    END
    
    SELECT
        @TOKEN = TOKEN,
        @TOKEN_EXPIRY_DATE = TOKEN_EXPIRY_DATE
    FROM TOKEN_DETAILS
    WHERE
        LOGIN_ID = @LOGIN_ID and
        NAME = @NAME and
        C_NAME = @C_NAME
        
    
    IF(@TOKEN IS NULL)
    BEGIN
        IF @DEBUG = 1 BEGIN
            PRINT "No token exists"
        END
        
        SELECT @TOKEN = NEWID(1)
        SELECT @TOKEN_EXPIRY_DATE = DATEADD(HOUR,12,GETUTCDATE())
        
        INSERT INTO TOKEN_DETAILS(
            LOGIN_ID,
            TOKEN,
            NAME,
            C_NAME,
            TOKEN_EXPIRY_DATE,
            CREATED_DATE,
            CREATED_BY
        )VALUES(
            @LOGIN_ID,
            @TOKEN,
            @NAME,
            @C_NAME,
            @TOKEN_EXPIRY_DATE,
            GETUTCDATE(),
            @USER
        )
        IF(@@ERROR !=0 )
        BEGIN
            SELECT @ERROR_MSG = CONVERT(CHAR(26),GETDATE(),109)+
            " - Error while inserting - "+ CONVERT(VARCHAR,@@ERROR)
            RAISEERROR 30000 @ERROR_MSG
        RETURN -1
        END
    END
    
    ELSE IF(@TOKEN_EXPIRY_DATE < GETUTCDATE())
    BEGIN
        IF @DEBUG = 1 BEGIN
            PRINT "TOKEN EXPIRES"
        END
        
        SELECT @TOKEN = NEWID(1)
        SELECT @TOKEN_EXPIRY_DATE = DATEADD(HOUR,12,GETUTCDATE())
        
        UPDATE
            TOKEN_DETAILS
        SET
            TOKEN = @TOKEN,
            TOKEN_EXPIRY_DATE = @TOKEN_EXPIRY_DATE
        WHERE
            LOGIN_ID = @LOGIN_ID and
            NAME = @NAME and
            C_NAME = @C_NAME
            
        IF(@@ERROR !=0 )
        BEGIN
            SELECT @ERROR_MSG = CONVERT(CHAR(26),GETDATE(),109)+
            " - Error while UPDATING - "+ CONVERT(VARCHAR,@@ERROR)
            RAISEERROR 30000 @ERROR_MSG
        RETURN -1
        END
    END
    
    ELSE IF @DEBUG = 1 
    BEGIN
        PRINT "TOKEN EXIST"
    END
    SELECT @TOKEN AS 'TOKEN', @TOKEN_EXPIRY_DATE AS 'TOKEN_EXPIRY_DATE'
END
GO

GRANT EXECUTE TAS_TEST TO ADMIN
GO

这是我为上述Sybase SQL编写的转换后的DB2 SQL。

CREATE OR REPLACE PROCEDURE TAS_TEST
(
    LOGIN_ID VARCHAR(20),
    NAME      VARCHAR(100),
    C_NAME    VARCHAR(100),
    USER      VARCHAR(20),
    DEBUG     SMALLINT DEFAULT 0
)

LANGUAGE SQL

BEGIN

DECLARE TOKEN_EXPIRY_DATE TIMESTAMP;
DECLARE TOKEN VARCHAR(36);
DECLARE ERR INT;
DECLARE ERROR_MSG VARCHAR(200);

SET LOGIN_ID = TRIM(LOGIN_ID);

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


SELECT
    TOKEN = TOKEN,
    TOKEN_EXPIRY_DATE = TOKEN_EXPIRY_DATE
FROM TOKEN_DETAILS
WHERE
    LOGIN_ID = LOGIN_ID and
    NAME = NAME and
    C_NAME = C_NAME;
    
IF(TOKEN IS NULL) THEN
BEGIN
    IF DEBUG = 1 THEN
        PRINT 'No token exists';
    END IF;
    
    SELECT TOKEN = GENERATE_UNIQUE(1) FROM SYSIBM.SYSDUMMY1;
    SELECT TOKEN_EXPIRY_DATE = TIMESTAMPADD(CURRENT_TIMESTAMP) FROM SYSIBM.SYSDUMMY1;
    
    INSERT INTO TOKEN_DETAILS(
        LOGIN_ID,
        TOKEN,
        NAME,
        C_NAME,
        TOKEN_EXPIRY_DATE,
        CREATED_DATE,
        CREATED_BY
    )VALUES(
        LOGIN_ID,
        TOKEN,
        NAME,
        C_NAME,
        TOKEN_EXPIRY_DATE,
        CURRENT_TIMESTAMP,
        USER
    );
END;
END IF;

IF(TOKEN_EXPIRY_DATE < CURRENT_TIMESTAMP)
BEGIN
    IF DEBUG = 1 THEN
        PRINT "TOKEN EXPIRES, UPDATING";
    END IF;
    
    SELECT TOKEN = GENERATE_UNIQUE(1) FROM SYSIBM.SYSDUMMY1;
    SELECT TOKEN_EXPIRY_DATE = TIMESTAMPADD(CURRENT_TIMESTAMP) FROM SYSIBM.SYSDUMMY1;
    
    UPDATE
        TOKEN_DETAILS
    SET
        TOKEN = TOKEN,
        TOKEN_EXPIRY_DATE = TOKEN_EXPIRY_DATE
    WHERE
        LOGIN_ID = LOGIN_ID and
        NAME = NAME and
        C_NAME = C_NAME;
END;
END IF;

IF (DEBUG = 1) THEN 
BEGIN
    PRINT "TOKEN EXIST";
END;
END IF;
SELECT TOKEN, TOKEN_EXPIRY_DATE FROM SYSIBM.SYSDUMMY1;
END;

GRANT EXECUTE TAS_TEST TO ADMIN;

有人能帮我一下我做错了什么地方吗。会有很大的帮助。

共有1个答案

钱瑞
2023-03-14

您的代码中有多个问题将阻止在DB2上进行编译。

考虑学习ANSI SQL PL(Db2-LUW使用的语法)。

从IBM在Db2-LUW服务器的samples目录、Db2-LUW知识中心和GitHub上提供的许多示例SQL PL过程中学习。

>

  • PRINT语句在ANSI SQL PL中无效。对于Db2-LUW,许多人使用调试调用dbms_output.put_line('some message');以及设置serveroutput on来进行会话。

    使用set语句为函数赋值变量。示例:set v_token=GENERATE_UNIQUE();

    只有在需要块特定的异常处理或条件处理时,才使用内部BEGIN.END块。没有必要使用begin...end块来分隔if中的一组语句。

    在例程中,使用select...INTO...从单例选择中分配变量。

    要对结果集列进行别名,请使用“colname AS colalias”语法

    若要返回结果集,请在签名中显式指定该结果集,并在末尾声明并打开一个游标。您的行select TOKEN,TOKEN_EXPIRY_DATE FROM sysibm.sysdummy1;无效。

    考虑将upsert作为单个MERGE语句的一部分来执行,这样可以使代码更加清晰,并简化错误检测和恢复。

  •  类似资料:
    • 我对DB2比较陌生,但对SQL不熟悉。我在从中减去几分钟后尝试语句时遇到以下错误: 我遇到的错误是: DB2 SQL 错误: SQLCODE=-104, SQLSTATE=42601, SQLERRMC=TCCAWZTXD;选择*;,驱动程序=3.66.46 如何修复此错误?

    • 本文向大家介绍意外的令牌相关面试题,主要包含被问及意外的令牌时的应答技巧和注意事项,需要的朋友参考一下 您的JavaScript表示使用JSONP模式发出Ajax请求(这涉及将元素插入文档中而不是使用XMLHttpRequest)。 您得到的响应是一个XML文档,而不是遵循JSONP模式的JavaScript程序,它类似于: 因为浏览器试图将XML作为JavaScript执行(不是),您会收到错误

    • 我在使用Struts2和Hibernate时遇到了以下错误: 我有这个方法: folling代码定义类之间的关系: Contrat类: Paiement类: PeriodePay等级: 此查询在phpMyAdmin中工作良好;你能告诉我出了什么问题吗 编辑1: 我在试着别搞错了: 我在控制台中得到结果: 但是使用jsp我在数据表中得不到结果,也许我必须修复迭代器

    • 问题内容: 为什么每次我做时:- 它只是解析很好,但是当我这样做时:- 它给我一个错误,说:- 问题答案: 您要它解析JSON文本(不是)。那是无效的JSON,字符串必须用双引号引起来。 如果要与第一个示例等效:

    • My HQL: 我收到以下错误: 我是HQL的新手。我想通过代码动态设置间隔值。我设置了等于比较的参数值。我读过http://www.mkyong.com/hibernate/hibernate-parameter-binding-examples/post,但我不知道在没有其他符号的情况下如何设置timeOffSet值。 斯纳克斯。 编辑: 我试过?及其工作良好,但我想用来实现这一点。

    • 我必须获得我的数据库(PostgreSQL)中的所有注册表,并使用不带大小写的。我试过使用标准,但ignoreCase()对我不起作用(我使用的是Hibernate3.6)。 我也尝试过使用ilike方法,但仍然不起作用。 这个版本也是: 因此,当我尝试在Hibernate中使用HQL创建查询时,会出现以下错误: 我的代码如下所示: 我做错了什么?