我无法理解我的 PL/SQL 触发器代码中的错误,因为我认为它是正确的

问题描述 投票:0回答:1

嗨,我是 PL/SQL 的初学者,我有用于将 csv 文件导入到我的 GLOBALTERRORISM 数据库的 PL/SQL 代码,这是迄今为止我的代码的最终版本。 我的问题是脚本输出不断给出此错误:

触发器 BEFORE_INSERT_GLOBALTERRORISM 已编译

线条/颜色错误


187/9 PL/SQL:忽略语句 187/61 PLS-00382:表达式类型错误 错误:检查编译器日志

触发 AFTER_INSERT_GLOBALTERRORISM 编译

触发器 BEFORE_UPDATE_GLOBALTERRORISM 已编译

线条/颜色错误


207/9 PL/SQL:语句被忽略 207/61 PLS-00382:表达式类型错误 错误:检查编译器日志

触发 AFTER_UPDATE_GLOBALTERRORISM 编译

触发器 BEFORE_DELETE_GLOBALTERRORISM 已编译

以前,我认为这可能是因为我有“案例”来检查该月的天数是否正确。所以代码是这样的:

    -- Validate day of the month
    CASE
        WHEN :NEW.IMONTH IN (1, 3, 5, 7, 8, 10, 12) THEN -- Months with 31 days
            IF :NEW.IDAY < 1 OR :NEW.IDAY > 31 THEN
                RAISE_APPLICATION_ERROR(-20003, 'Day must be between 1 and 31 for the given month.');
            END IF;
        WHEN :NEW.IMONTH IN (4, 6, 9, 11) THEN -- Months with 30 days
            IF :NEW.IDAY < 1 OR :NEW.IDAY > 30 THEN
                RAISE_APPLICATION_ERROR(-20004, 'Day must be between 1 and 30 for the given month.');
            END IF;
        WHEN :NEW.IMONTH = 2 THEN -- February, handle leap year
            IF (:NEW.IYEAR MOD 4 = 0 AND :NEW.IYEAR MOD 100 <> 0) OR (:NEW.IYEAR MOD 400 = 0) THEN
                IF :NEW.IDAY < 1 OR :NEW.IDAY > 29 THEN
                    RAISE_APPLICATION_ERROR(-20005, 'Day must be between 1 and 29 for February in a leap year.');
                END IF;
            ELSE
                IF :NEW.IDAY < 1 OR :NEW.IDAY > 28 THEN
                    RAISE_APPLICATION_ERROR(-20006, 'Day (IDAY) must be between 1 and 28 for February in a non-leap year.');
                END IF;
            END IF;
    END CASE;

我把它改成这样:

    -- Validate day of the month
    IF :NEW.IMONTH IN (1, 3, 5, 7, 8, 10, 12) THEN -- Months with 31 days
        IF :NEW.IDAY < 1 OR :NEW.IDAY > 31 THEN
                RAISE_APPLICATION_ERROR(-20003, 'Day must be between 1 and 31 for the given month.');
        END IF;
    END IF;
        
    IF :NEW.IMONTH IN (4, 6, 9, 11) THEN -- Months with 30 days
        IF :NEW.IDAY < 1 OR :NEW.IDAY > 30 THEN
                RAISE_APPLICATION_ERROR(-20004, 'Day must be between 1 and 30 for the given month.');
        END IF;
    END IF;
        
        IF :NEW.IMONTH = 2 THEN -- February, handle leap year
            IF (:NEW.IYEAR MOD 4 = 0 AND :NEW.IYEAR MOD 100 <> 0) OR (:NEW.IYEAR MOD 400 = 0) THEN
                IF :NEW.IDAY < 1 OR :NEW.IDAY > 29 THEN
                    RAISE_APPLICATION_ERROR(-20005, 'Day must be between 1 and 29 for February in a leap year.');
                END IF;
            ELSE
                IF :NEW.IDAY < 1 OR :NEW.IDAY > 28 THEN
                    RAISE_APPLICATION_ERROR(-20006, 'Day (IDAY) must be between 1 and 28 for February in a non-leap year.');
                END IF;
            END IF;
        END IF;

但一切都没有改变。我尝试删除它,看看这个代码片段是否是问题所在,但没有再发生任何变化......

    SELECT COUNT(*) s
    INTO v_count
    FROM GLOBALTERRORISM
    WHERE IYEAR = :NEW.IYEAR
      AND IMONTH = :NEW.IMONTH
      AND IDAY = :NEW.IDAY;
    -- Generate the EVENTID based on IYEAR, IMONTH, IDAY, and the occurrence count
    :NEW.EVENTID := TO_CHAR(:NEW.IYEAR, 'FM0000') ||
                    TO_CHAR(:NEW.IMONTH, 'FM00') ||
                    TO_CHAR(:NEW.IDAY, 'FM00') ||
                    TO_CHAR(v_count + 1, 'FM0000');
plsql
1个回答
0
投票

您是否在触发器中使用此格式(更新表后...)?

CREATE OR REPLACE TRIGGER AFTER_UPDATE_GLOBALTERRORISM
AFTER UPDATE
   ON GLOBALTERRORISM
   FOR EACH ROW

BEGIN
    -- Validate day of the month
    CASE
        WHEN :NEW.IMONTH IN (1, 3, 5, 7, 8, 10, 12) THEN -- Months with 31 days
            IF :NEW.IDAY < 1 OR :NEW.IDAY > 31 THEN
                RAISE_APPLICATION_ERROR(-20003, 'Day must be between 1 and 31 for the given month.');
            END IF;
        WHEN :NEW.IMONTH IN (4, 6, 9, 11) THEN -- Months with 30 days
            IF :NEW.IDAY < 1 OR :NEW.IDAY > 30 THEN
                RAISE_APPLICATION_ERROR(-20004, 'Day must be between 1 and 30 for the given month.');
            END IF;
        WHEN :NEW.IMONTH = 2 THEN -- February, handle leap year
            IF (:NEW.IYEAR MOD 4 = 0 AND :NEW.IYEAR MOD 100 <> 0) OR (:NEW.IYEAR MOD 400 = 0) THEN
                IF :NEW.IDAY < 1 OR :NEW.IDAY > 29 THEN
                    RAISE_APPLICATION_ERROR(-20005, 'Day must be between 1 and 29 for February in a leap year.');
                END IF;
            ELSE
                IF :NEW.IDAY < 1 OR :NEW.IDAY > 28 THEN
                    RAISE_APPLICATION_ERROR(-20006, 'Day (IDAY) must be between 1 and 28 for February in a non-leap year.');
                END IF;
            END IF;
    END CASE;
END;

/
© www.soinside.com 2019 - 2024. All rights reserved.