1

我正在尝试在 PL/SQL 中创建一个插入前触发器,这将防止将空数据插入到表行中。(强制执行非空条件并防止插入数字或特殊字符的触发器。

这是我创建的表。

CREATE TABLE CUSTOMER 
(
  CUSTOMER_ID INTEGER 
, CUST_FORENAME VARCHAR2(50) NOT NULL 
, CUST_SURNAME VARCHAR2(50) NOT NULL 
, GENDER CHAR(1) 
, EMAIL_ADDRESS VARCHAR2(30) NOT NULL 
, CONSTRAINT CUSTOMER_PK PRIMARY KEY (CUSTOMER_ID)
  ENABLE 
);

还有我创建的触发器。

create or replace
TRIGGER CUS_MAND before insert OR update on CUSTOMER
begin
  CASE
    WHEN :NEW.CUST_FORENAME = NULL
      THEN DBMS_OUTPUT.PUT_LINE ('Please enter customer forename.');
    WHEN :NEW.CUST_SURNAME = NULL
      THEN DBMS_OUTPUT.PUT_LINE ('Please enter customer surname.');
    WHEN :NEW.EMAIL_ADDRESS = NULL
      THEN DBMS_OUTPUT.PUT_LINE ('Please enter customer email address.');
  END CASE;
END;

但是这个触发器没有成功。有人可以为我解决问题吗?

4

2 回答 2

4

正如@APC 指出的那样,为此目的使用 NOT NULL 约束比使用触发器更有意义。

但是,如果您想使用触发器,您应该引发错误而不是仅仅打印到 DBMS_OUTPUT,因为

  • 打印消息不会阻止插入错误数据
  • 通常,INSERTS / UPDATES 将由某种客户端程序运行,并且 DBMS_OUTPUT 不会显示在此客户端程序中

除此之外,您的触发器中有几个错误:

  • 您需要将触发器声明为 FOR EACH ROW,否则,您将无法使用 :NEW 和 :OLD (因为您的触发器将在每个语句中触发一次,而不是每一次)
  • 您的 CASE 语句缺少 DEFAULT 分支,因此如果所有检查都成功,您将在执行期间收到错误;我会改用 IF

一种可能的解决方案:

create or replace trigger CUS_MAND before insert OR update on CUSTOMER
for each row        
begin
  if :NEW.CUST_FORENAME is NULL THEN
    RAISE_APPLICATION_ERROR(-20001,
                            'Please enter customer forename.');
  end if;
  if :NEW.CUST_SURNAME is NULL THEN
    RAISE_APPLICATION_ERROR(-20002,
                            'Please enter customer surname.');
  end if;
  if :NEW.EMAIL_ADDRESS is NULL THEN
    RAISE_APPLICATION_ERROR(-20003,
                            'Please enter customer email address.');
  END if;
END;

在这里,我使用 RAISE_APPLICATION_ERROR 来引发用户定义的异常;您可以对所有错误使用相同的错误编号 (-20001),也可以使用编号来区分它们。

于 2013-03-25T15:06:10.193 回答
0

您以错误的方式检查空值:

:NEW.CUST_FORENAME = NULL

空值检查必须使用“is null”或“is not null”。相等运算符不起作用。没有什么与 NULL 相同或不同。

因此,如果 A := null:

a = Null => false
a != null => false
a is null => true
a is not null => false

此外,您的触发器应该是 Frank Schmitt 指出的“FOR EACH ROW”。

如果您的验证很简单,则使用非空约束或检查约束可能是最佳选择。

于 2013-03-25T15:15:56.043 回答