1

PL / SQLで挿入前トリガーを作成しようとしています。これにより、テーブル行に空のデータが挿入されなくなります。(null以外の条件を強制し、数字や特殊文字の挿入を防ぐトリガー。

これは私が作成したテーブルです。

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が指摘したように、この目的にはトリガーよりもNOTNULL制約を使用する方が理にかなっています。

ただし、トリガーを使用する場合は、DBMS_OUTPUTに出力するだけでなく、エラーを発生させる必要があります。

  • メッセージを印刷しても、間違ったデータの挿入を防ぐことはできません
  • usually, INSERTS / UPDATES will be run by some kind of client program, and DBMS_OUTPUT will not be shown in this client program

Apart from that, you've got a couple of errors in your trigger:

  • you need to declare your trigger as FOR EACH ROW, otherwise, you won't be able to use :NEW and :OLD (because your trigger will be fired once per statement, not once per row)
  • your CASE statement lacks the DEFAULT branch, so if all checks are successfull, you'll get an error during execution; I'd use an IF instead

One possible solution:

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;

Here, I use RAISE_APPLICATION_ERROR to raise a user-defined exception; you can either use the same error number (-20001) for all errors or use the number to distinguish between them.

于 2013-03-25T15:06:10.193 に答える
0

You are checking for null values the wrong way:

:NEW.CUST_FORENAME = NULL

Null values checking must use "is null" or "is not null". Equal operator doesn't work. Nothing is ever equal or different to NULL.

So, if A := null:

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

Also, your trigger should be "FOR EACH ROW" as pointed by Frank Schmitt.

If your validations are simple, using not null constraints or check constraints might be a best option.

于 2013-03-25T15:15:56.043 に答える