0

我正在尝试确定存储过程中的行或导致警告/未找到的最后一个 SQL 语句。作为一种解决方法,我使用手动设置的临时变量来确定在存储过程的哪个部分出现警告。

-- Create an ErrorLog table
Create Table SCHEMA.ErrorLog_lrc_test                                                        
  (                                 
   ErrSQLCODE     Integer ,                                   
   Codepart    Char(1),                             
   Type           Char(1) ,                                  
   MsgText        VarChar(1024));

CREATE OR REPLACE PROCEDURE SCHEMA.test_warning(IN divisor INT)
LANGUAGE SQL
BEGIN
-- Define variables
DECLARE codepart_var Char(1);

DECLARE test_INT INT;

-- Define sqlcode
DECLARE SQLCODE INTEGER;
       
--Define Warning-Handler
DECLARE CONTINUE HANDLER FOR SQLWARNING, NOT FOUND 
    BEGIN 
    INSERT INTO SCHEMA.ErrorLog_lrc_test(ErrSQLCODE, Codepart, TYPE, MsgText) 
        VALUES(SQLCODE, codepart_var, 'W', SYSPROC.SQLERRM(SQLCODE));
    END;
 
-- Set temporary variable to 'a' to get part of code where warning occured
SET codepart_var = 'a';

-- Create Not Found (Sqlcode 100)
INSERT INTO SCHEMA.ErrorLog_lrc_test
SELECT NULL, NULL, NULL, NULL FROM "SYSIBM".SYSDUMMY1
WHERE 1 = 0 ;

END 

call SCHEMA.test_warning(0);

SELECT *
FROM SCHEMA.ErrorLog_lrc_test;

我得到以下信息:

错误代码 代码部分 类型 MSGTEXT
100 一个 W SQL0100W 未找到 FETCH、UPDATE 或 DELETE 行;或者查询的结果是一个空表。

我知道对于错误,有一个函数 DBMS_UTILITY.FORMAT_ERROR_BACKTRACE 可用于跟踪错误。不幸的是,该功能不会跟踪警告。还有一个函数 DBMS_UTILITY.FORMAT_CALL_STACK,但这也不起作用。

是否有另一种/更好的方法来记录导致警告/未找到的存储过程中的特定行或 SQL 语句?

4

1 回答 1

0

不,据我所知,目前没有内置的警告功能。在这里仔细考虑你的动机。

程序员可以通过在例程中使用异常处理程序(或多个异常处理程序)来捕获警告,并可以决定记录此类事件(或在极端情况下,通过引发新异常将它们转换为错误,然后通过DBMS_UTILITY.FORMAT*方法)。但这可能是不明智的,除非在开发环境中。

您的例程可能有一个continue handlerfor 警告,您可以在其中检查 SQLSTATE,并有条件地决定记录特定的 SQLSTATES。记录 SQLSTATE '02000'(sqlcode 100 - 未找到行)可能是愚蠢的,因为这与大多数警告一样是良性的。但是一些警告可能会提示其他问题,例如数据质量/转换/截断或可能值得记录的优化问题。

我不知道有任何工具可以帮助解决这个问题,或者为警告提供行号,或者为客户端查询集成此类工作。

DBA 可以(对于 Db2-LUW)使用 Db2 服务器上的其他工具来更密切地观察正在执行的语句和包。例如监控db2pd、、、db2cos审计等。但这条路线似乎是用大锤来破解一个可能不存在的坚果,因此需要仔细检查你的动机。

于 2021-02-15T11:59:31.957 回答