【问题标题】:Getting SQLCODE and SQLSTATE from inner SQL call in procedure DB2从过程 DB2 中的内部 SQL 调用获取 SQLCODE 和 SQLSTATE
【发布时间】:2019-04-19 10:12:16
【问题描述】:

我有这个程序:

 CREATE OR REPLACE PROCEDURE LOG_TEST
                                 ( IN QUERY VARCHAR(24576),
                                   IN LOGTBL_VAR VARCHAR(20) ) 
                                   LANGUAGE SQL 
                                   SPECIFIC LOG_TEST
BEGIN
DECLARE SQLCODE INTEGER DEFAULT 0;
DECLARE SQLSTATE CHAR(5) DEFAULT '00000';
DECLARE V_QUERY VARCHAR(24576);
DECLARE V_ERRORMSG VARCHAR(2048) DEFAULT '';
DECLARE V_SQLCODE INTEGER DEFAULT 0;
DECLARE V_SQLSTATE CHAR(5) DEFAULT '00000';
DECLARE V_INS_STRING VARCHAR(1024);
DECLARE STMT STATEMENT;
DECLARE STMT_INS STATEMENT;
DECLARE CONTINUE HANDLER FOR SQLEXCEPTION, SQLWARNING,NOT FOUND
BEGIN
GET DIAGNOSTICS
EXCEPTION
1 V_ERRORMSG = MESSAGE_TEXT;
VALUES(SQLSTATE,SQLCODE)INTO V_SQLSTATE, V_SQLCODE;
END;

SET V_QUERY = QUERY;
PREPARE STMT FROM V_QUERY;
EXECUTE STMT;

SET V_QUERY     = REPLACE(V_QUERY,'''', ''''''); 
SET V_INS_STRING= 'INSERT INTO '||LOGTBL_VAR||'(QUERY, SQL_CODE, SQL_STATE, ERROR_MSG, BEZUG, TIME) VALUES ('''||V_QUERY||''', '||V_SQLCODE||', '''||V_SQLSTATE||''', '''||V_ERRORMSG||''')';
 PREPARE STMT_INS FROM V_INS_STRING;
 EXECUTE STMT_INS;

 END@

程序运行良好,一切都很好,但只有一件事。如果通过参数给出的查询无效,我总是得到 SQLCODE -727 和 SQLSTATE 56098,这是过程本身的一般错误,但是我需要查询导致的 SQLCODE 和 SQLSTATE,以便我可以看到有什么问题查询自己。我怎么能得到那个?

我在 Windows v10.5 上运行 DB2

有什么想法吗?

谢谢。

【问题讨论】:

    标签: sql stored-procedures error-handling db2


    【解决方案1】:

    您的 INSERT 语句不正确 - 列数 (6) 和值 (4) 不同。 您在 LOG_TEST 表中究竟得到了什么?

    CREATE OR REPLACE PROCEDURE LOG_TEST (
      IN QUERY VARCHAR(24576)
    , IN LOGTBL_VAR VARCHAR(20)
    ) 
    SPECIFIC LOG_TEST
    BEGIN
    DECLARE SQLCODE INTEGER DEFAULT 0;
    DECLARE SQLSTATE CHAR(5) DEFAULT '00000';
    DECLARE V_ERRORMSG VARCHAR(2048) DEFAULT '';
    DECLARE V_SQLCODE INTEGER DEFAULT 0;
    DECLARE V_SQLSTATE CHAR(5) DEFAULT '00000';
    DECLARE CONTINUE HANDLER FOR SQLEXCEPTION, SQLWARNING,NOT FOUND
    BEGIN
      GET DIAGNOSTICS EXCEPTION 1 V_ERRORMSG = MESSAGE_TEXT;
      VALUES(SQLSTATE,SQLCODE) INTO V_SQLSTATE, V_SQLCODE;
    END;
    
    EXECUTE IMMEDIATE QUERY;
    
    PREPARE STMT_INS FROM 'INSERT INTO '||LOGTBL_VAR||'(QUERY, SQL_CODE, SQL_STATE, ERROR_MSG) VALUES (?,?,?,?)';
    EXECUTE STMT_INS USING QUERY, V_SQLCODE, V_SQLSTATE, V_ERRORMSG;
    
    END@
    
    CREATE TABLE LOG_TEST(QUERY VARCHAR(1000), SQL_CODE INT, SQL_STATE CHAR(5), ERROR_MSG VARCHAR(1000)) IN USERSPACE1@
    
    CALL LOG_TEST('DELETE FROM LOG_TEST - WRONG QUERY', 'LOG_TEST')@
    SELECT * FROM LOG_TEST@
    

    如果你想运行 SELECT 语句并得到结果,那么:

    CREATE OR REPLACE PROCEDURE LOG_TEST (
      IN QUERY VARCHAR(24576)
    , IN LOGTBL_VAR VARCHAR(20)
    , OUT RES INT
    ) 
    SPECIFIC LOG_TEST
    BEGIN
    DECLARE SQLCODE INTEGER DEFAULT 0;
    DECLARE SQLSTATE CHAR(5) DEFAULT '00000';
    DECLARE V_ERRORMSG VARCHAR(2048) DEFAULT '';
    DECLARE V_SQLCODE INTEGER DEFAULT 0;
    DECLARE V_SQLSTATE CHAR(5) DEFAULT '00000';
    DECLARE V_QUERY VARCHAR(24576);
    DECLARE CONTINUE HANDLER FOR SQLEXCEPTION, SQLWARNING,NOT FOUND
    BEGIN
      GET DIAGNOSTICS EXCEPTION 1 V_ERRORMSG = MESSAGE_TEXT;
      VALUES(SQLSTATE,SQLCODE) INTO V_SQLSTATE, V_SQLCODE;
    END;
    
    SET V_QUERY='SET (?) = ('||REPLACE(QUERY, '''', '''''')||')';
    PREPARE STMT_SEL FROM V_QUERY;
    EXECUTE STMT_SEL INTO RES;
    
    PREPARE STMT_INS FROM 'INSERT INTO '||LOGTBL_VAR||'(QUERY, SQL_CODE, SQL_STATE, ERROR_MSG) VALUES (?,?,?,?)';
    EXECUTE STMT_INS USING QUERY, V_SQLCODE, V_SQLSTATE, V_ERRORMSG;
    
    END@
    

    【讨论】:

    • 我简化了源有 6 个值。现在它适用于除选择查询之外的所有内容。您可以将执行立即用于选择查询,例如将立即查询执行到变量中吗? (查询是一个选择计数(*))
    • 我试过 'SET(?)=('||QUERY||')' INTO VARIABLE;但这不会编译
    • 您不能对 SELECT 语句运行立即执行。我已经更新了示例。
    • 运行 SELECT 语句并且不消耗它们的结果是很不寻常的。运行 select 语句只是为了记录他们的调用?真奇怪……
    • DECLARE C1 CURSOR FOR STMT_SEL; ... PREPARE STMT_SEL FROM V_QUERY; OPEN C1; CLOSE C1; 或者甚至只是停止准备所有类型的查询,如果您不想真正运行它们...
    猜你喜欢
    • 1970-01-01
    • 2014-01-22
    • 2017-04-02
    • 2013-08-24
    • 1970-01-01
    • 1970-01-01
    • 2011-11-20
    • 1970-01-01
    • 2017-04-01
    相关资源
    最近更新 更多