简体   繁体   English

PL/SQL 触发器在插入语句之前检查值

[英]PL/SQL Trigger to check value before insert statement

I am new to PL/SQL and I have an issue regarding a trigger I am trying to implement.我是 PL/SQL 的新手,我对尝试实现的触发器有疑问。

The triggers purpose is to check a monetary value before it's inserted into the table to see if someone made a mistake during inserting.触发器的目的是在插入表之前检查货币值,以查看是否有人在插入过程中犯了错误。 If they have, they will be given a message stating the value is incorrect.如果有,他们将收到一条消息,说明该值不正确。 The values are in the billions so for now I am just checking if the value entered is above 10000 or not.这些值是数十亿,所以现在我只是检查输入的值是否高于 10000。

The trigger I currently have is;我目前拥有的触发器是;

CREATE TRIGGER Check_Value
BEFORE INSERT OR UPDATE OF "Potential Annual Value By 2026" ON AIPOTENTIALVALUEFORHEALTHCARE
BEGIN
IF (NEW."Potential Annual Value By 2026" < 10000.00) THEN
DBMS_OUTPUT.put_line('Value typed was incorrect');
ELSIF (NEW."Potential Annual Value By 2026" >= 10000.00) THEN
INSERT INTO AIPOTENTIALVALUEFORHEALTHCARE VALUES(NEW.ValueID, NEW.ApplicationID, NEW."Application Name", NEW.KeyDriverForAdoptionID, NEW."KeyDriverDescription", NEW."Potential Annual Value By 2026");
END IF;
END;

This will not work due to an error:由于错误,这将不起作用:

PLS-00201: identifier NEW.'Potential Annual Value By 2026' must be declared

My guess is that I have set the trigger incorrectly and that it doesn't know which value to check when it runs the trigger.我的猜测是我错误地设置了触发器,并且它不知道在运行触发器时要检查哪个值。 From some research, I tried to use.NEW to pass the values of the statement into the trigger however I am not sure if this is the correct implementation.根据一些研究,我尝试使用 .NEW 将语句的值传递到触发器中,但是我不确定这是否是正确的实现。

I had tried the method already posted;我已经尝试过已经发布的方法;

CREATE TRIGGER Check_Value
BEFORE INSERT OR UPDATE OF "Potential Annual Value By 2026" ON AIPOTENTIALVALUEFORHEALTHCARE
BEGIN
  IF (:NEW."Potential Annual Value By 2026" < 10000.00) THEN
    DBMS_OUTPUT.put_line('Value typed was incorrect');
  ELSIF (:NEW."Potential Annual Value By 2026" >= 10000.00) THEN
    INSERT INTO AIPOTENTIALVALUEFORHEALTHCARE VALUES
      (:NEW.ValueID, :NEW.ApplicationID, :NEW."Application Name", 
       :NEW.KeyDriverForAdoptionID, :NEW."KeyDriverDescription", 
       :NEW."Potential Annual Value By 2026");
  END IF;
END;

and recieved a different error:并收到不同的错误:

ORA-04082: NEW or OLD references not allowed in table level triggers
04082. 00000 -  "NEW or OLD references not allowed in table level triggers"
*Cause:    The trigger is accessing "new" or "old" values in a table trigger.
*Action:   Remove any new or old references.

If this error is stating I can't use NEW references in a table level trigger, how would I be able to verify the contents of the insert statement before it is committed?如果此错误表明我不能在表级触发器中使用 NEW 引用,我将如何在插入语句提交之前验证它的内容?

You are missing colons before the NEW keywords and the FOR EACH ROW clause.您在NEW关键字和 FOR EACH ROW 子句之前缺少冒号。 Also you do not need to (and must not) re-issue the INSERT within the trigger, it will happen anyway (if no error is raised):此外,您不需要(也不能)在触发器中重新发出 INSERT,无论如何它都会发生(如果没有引发错误):

CREATE TRIGGER Check_Value
BEFORE INSERT OR UPDATE OF "Potential Annual Value By 2026" ON AIPOTENTIALVALUEFORHEALTHCARE
FOR EACH ROW
BEGIN
  IF (:NEW."Potential Annual Value By 2026" < 10000.00) THEN
    RAISE_APPLICATION_ERROR(-20001, 'Value typed was incorrect');
  END IF;
END;

I'm sure this is just a training example, but DBMS_OUTPUT.PUT_LINE is not a suitable method for raising errors to users as its output can only be seen when using develpper tools like SQL Developer.我确信这只是一个培训示例,但 DBMS_OUTPUT.PUT_LINE 不是向用户提出错误的合适方法,因为它的 output 只有在使用 SQL Developer 等开发工具时才能看到。 Use RAISE_APPLICATION_ERROR .使用RAISE_APPLICATION_ERROR Also it doesn't actually raise an exception, so it won't prevent the insert at all.而且它实际上并没有引发异常,所以它根本不会阻止插入。

In fact, this check might be better done with a CHECK constraint - assuming the column value must never be under 10000:实际上,使用 CHECK 约束可能会更好地完成此检查 - 假设列值决不能低于 10000:

ALTER TABLE AIPOTENTIALVALUEFORHEALTHCARE
   ADD CONSTRAINT AIPOTENTIALVALUEFORHEALTHCARE_CHK_VALUE
      CHECK ("Potential Annual Value By 2026" >= 10000);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM