嗨,我是 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');
您是否在触发器中使用此格式(更新表后...)?
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;
/