如何修复 SQL Oracle 中未触发的基本触发器



我一直在尝试让这个触发器工作,但由于某种原因,在我更新/插入表中的内容之前它甚至没有激活。此触发器的目的(我需要通过触发器执行此操作)是确保 DISCS 表中的所有条目在 FORMAT 属性中都有"L"或"S"。否则,不应插入/更新该条目。

我试图添加一行来检查触发器是否被激活("buenos dias"行),但似乎不是出于某种原因。我只是一个有触发器的初学者,我确定错误真的很愚蠢,但我就是找不到它。

触发器的代码为:

CREATE OR REPLACE TRIGGER FORMAT_T
BEFORE INSERT OR UPDATE OF FORMAT
ON DISCS
FOR EACH ROW
DECLARE
bad_format EXCEPTION;
BEGIN
DBMS_OUTPUT.PUT_LINE('Buenos dias.');
IF :NEW.FORMAT != 'S' AND :NEW.FORMAT != 'L' THEN
RAISE bad_format;
END IF;
EXCEPTION
WHEN bad_format THEN
DBMS_OUTPUT.PUT_LINE('Bad format, could not insert/update.');
END FORMAT_T;

编译触发器后,我尝试更新以下行(使用第一行的 ID 只是为了能够轻松测试它):

UPDATE DISCS
SET FORMAT = 'W'
WHERE ID = 1;

这应该返回一个错误,因为我将其更新为的格式不是"L"也不是"S",而是该行只是毫无问题地更新,甚至没有弹出"buenos dias"行。user_errors表中也没有错误。

提前感谢您的帮助。

您发布的触发代码工作正常。真正的问题由此揭示:

甚至没有弹出"布宜诺斯迪亚斯"线

显然,您正在运行禁用DBMS_OUTPUT的环境中。因此,更新按预期失败,您只是看不到该消息。我们可以通过从触发器代码中删除 EXCEPTION 块来轻松演示这一点,如此 SQL Fiddle 所示。

启用DBMS_OUTPUT取决于您的执行环境。在 SQL*Plus 中运行set serveroutput on。在 Oracle SQL Developer 中,选择"查看>Dbms_Output"并设置连接。在 PL/SQL 开发人员中,在 SQL 工作表上启用DBMS_OUTPUT。等等。


顺便说一下,触发器是强制执行此规则的错误方式。正确的方法是在列上定义检查约束。

alter table disks add constraint disc_format_ck 
check (format in ('S', 'L'));

您的问题与

IF :NEW.FORMAT != 'S' AND :NEW.FORMAT != 'L' THEN

陈述

只需替换为

IF :NEW.FORMAT not in ('S','L') THEN

但是,我更喜欢使用检查约束:

ALTER TABLE discs
ADD CONSTRAINT chk_format CHECK (format in ('S','L'))

在这种情况下,当输入'S''L'以外的字符时,数据库会自动抛出"检查约束被违反">,而无需触发器。

使用raise_application_error:

raise_application_error(-20010,"格式错误,无法插入/更新。

CREATE OR REPLACE TRIGGER FORMAT_T
BEFORE INSERT OR UPDATE
OF FORMAT
ON DISCS
REFERENCING NEW AS NEW OLD AS OLD
FOR EACH ROW
BEGIN 
IF :NEW.FORMAT not in( 'S' , 'L') THEN    
raise_application_error(-20010,'Bad format, could not insert/update.');
END IF;   
EXCEPTION
WHEN OTHERS THEN    
DBMS_OUTPUT.PUT_LINE('OTHERS EXCEPTION');   
END FORMAT_T;

您需要将服务器输出设置为打开状态以执行触发器。为此,您可以在sql plus中键入以下命令

set serveroutput on

最新更新