簡體   English   中英

SQL-在IBM DB2存儲過程中為循環聲明游標

[英]SQL - Declare cursor inside for loop in IBM DB2 Stored Procedure

我試圖使用for循環從游標中遍歷存儲過程中的結果。 循環在以下示例中正常運行:

CREATE OR REPLACE PROCEDURE ML_ANOMALY_EVENT_CREATOR ()
    DYNAMIC RESULT SETS 1
P1: BEGIN

    DECLARE DATETIME_TEMP TIMESTAMP(6);
    DECLARE TAG_GROUP_TEMP VARCHAR(50);
    DECLARE EVENT_CODE VARCHAR(100);
    DECLARE STMT VARCHAR(1000);
    SET STMT = 'INSERT INTO ML_ANOMALY_EVENTS VALUES(?, ?, CURRENT TIMESTAMP, ?, CURRENT TIMESTAMP)';
    PREPARE S1 FROM STMT;

    FOR v AS AD_DATA CURSOR FOR (SELECT DATETIME, TAG_GROUP FROM ML_AD_MV WHERE DATETIME > (SELECT MAX(DATETIME_END) FROM ML_ANOMALY_EVENTS) AND ANOMALY=2 ORDER BY 2, 1)
        DO
            SET DATETIME_TEMP = v.DATETIME;
            SET TAG_GROUP_TEMP = v.TAG_GROUP;
            SET EVENT_CODE = 'TEST';
            EXECUTE S1 USING EVENT_CODE, TAG_GROUP_TEMP, DATETIME_TEMP;
    END FOR;

END P1

當我改為嘗試以下操作時,它將失敗。 我想借助聲明的變量從某個表中提取結果,並且如果結果包含任何行,則僅執行某些操作(在本示例中為插入):

CREATE OR REPLACE PROCEDURE ML_ANOMALY_EVENT_CREATOR ()
    DYNAMIC RESULT SETS 1
P1: BEGIN

    DECLARE DATETIME_TEMP TIMESTAMP(6);
    DECLARE TAG_GROUP_TEMP VARCHAR(50);
    DECLARE EVENT_CODE VARCHAR(100);
    DECLARE STMT VARCHAR(1000);
    SET STMT = 'INSERT INTO ML_ANOMALY_EVENTS VALUES(?, ?, CURRENT TIMESTAMP, ?, CURRENT TIMESTAMP)';
    PREPARE S1 FROM STMT;

    FOR v AS AD_DATA CURSOR FOR (SELECT DATETIME, TAG_GROUP FROM ML_AD_MV WHERE DATETIME > (SELECT MAX(DATETIME_END) FROM ML_ANOMALY_EVENTS) AND ANOMALY=2 ORDER BY 2, 1)
        DO
            SET DATETIME_TEMP = v.DATETIME;
            SET TAG_GROUP_TEMP = v.TAG_GROUP;
            SET EVENT_CODE = 'TEST';
            --EXECUTE S1 USING EVENT_CODE, TAG_GROUP_TEMP, DATETIME_TEMP;

            DECLARE EVENT_CHECKER CURSOR FOR
                SELECT * FROM ML_ANOMALY_EVENTS WHERE TAG_GROUP=TAG_GROUP_TEMP AND DATETIME >= DATETIME_TEMP;

            OPEN EVENT_CHECKER;
                IF (EVENT_CHECKER IS FOUND) THEN
                    EXECUTE S1 USING EVENT_CODE, TAG_GROUP_TEMP, DATETIME_TEMP;
                END IF;
            CLOSE EVENT_CHECKER;

    END FOR;

END P1

我該如何解決?

無需使用event_checker游標。 嘗試

if ((SELECT count(*) FROM ML_ANOMALY_EVENTS 
     WHERE TAG_GROUP=TAG_GROUP_TEMP AND DATETIME >= DATETIME_TEMP ) > 0) then
   EXECUTE S1 USING EVENT_CODE, TAG_GROUP_TEMP,DATETIME_TEMP;
end if

盡管蔡文義的答案可行,但在這里使用EXISTS謂詞代替聚合會更有效:

IF EXIST (SELECT 1 FROM ML_ANOMALY_EVENTS 
          WHERE TAG_GROUP=TAG_GROUP_TEMP AND DATETIME >= DATETIME_TEMP) THEN ...

特別是如果您希望該條件在大多數情況下都是正確的。 找到符合搜索條件的單個記錄后, EXISTS將立即返回,而具有COUNT(*)的查詢將必須讀取所有匹配的記錄。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM