创建更新触发器时变量名称出错

时间:2016-12-11 16:45:06

标签: oracle plsql triggers

我正在尝试创建一个触发器,允许输入尺寸小 - 大的衣物,但触发器会根据插入将大小更改为S M或L.

我在if语句中遇到错误的绑定变量错误,我不知道为什么,因为它与Products表中的列名相同。

产品表:

CREATE TABLE "user"."PRODUCTS" 
   (    "PID" NUMBER(6,0), 
    "PRODUCT_NAME" VARCHAR2(255 BYTE), 
    "QUANTITY" NUMBER, 
    "PRODUCT_SIZE" VARCHAR2(255 BYTE), 
    "PRODUCT_VALUE" NUMBER, 
     PRIMARY KEY ("PID")

尺寸触发:

create or replace TRIGGER sizeTrigger
BEFORE INSERT OR UPDATE
   ON PRODUCTS
BEGIN
   --smalls--
    IF :NEW.product_size = 's' THEN
    ::NEW.PRODUCT_SIZE := 'S';
    elsif ::NEW.PRODUCT_SIZE = 'S' THEN
       ::NEW.product_size := 'S';
     elsif ::NEW.PRODUCT_SIZE = 'small'THEN
       ::NEW.product_size := 'S';
       elsif ::NEW.PRODUCT_SIZE = 'SMALL' THEN
       ::NEW.product_size := 'S';
    --MEDIUM--
    elsif ::NEW.PRODUCT_SIZE = 'm' THEN
       ::NEW.product_size := 'M';
    elsif ::NEW.PRODUCT_SIZE = 'm' THEN
       ::NEW.product_size := 'M';
    elsif ::NEW.PRODUCT_SIZE = 'medium' THEN
       ::NEW.product_size := 'M';
        elsif ::NEW.PRODUCT_SIZE = 'MEDIUM' THEN
       ::NEW.product_size := 'M';
     --large
      elsif ::NEW.PRODUCT_SIZE = 'l' THEN
       ::NEW.product_size := 'L';
    elsif ::NEW.PRODUCT_SIZE = 'L' THEN
       ::NEW.product_size := 'L';
    elsif ::NEW.PRODUCT_SIZE = 'large' THEN
       ::NEW.product_size := 'L';
        elsif ::NEW.PRODUCT_SIZE = 'LARGE' THEN
       ::NEW.product_size := 'L';
      else
          raise exception_error;        
        END IF;
EXCEPTION
   WHEN exception_error THEN
    DBMS_OUTPUT.PUT_LINE('Size must be "s,m,l,small, medium, large");
END;

3 个答案:

答案 0 :(得分:1)

在现实生活中,我们的目标是使用检查约束来强制执行业务规则。

alter table products
    add constraint check_product_size
       check (product_size in ('S', 'M', 'L'));

我更希望应用程序为用户提供一系列有效尺寸;如果他们输入的数据在查询时神秘地改变或丢失,他们会觉得很困惑。但是如果你想这样做,这里是最简单的触发器(结合上面的检查约束):

create or replace trigger sizetrigger
before insert or update
   on products
   for each row
begin
   :new.product_size := upper(substr(:new.product_size,1,1));
end; 

答案 1 :(得分:0)

:

使用单::而非:new
create or replace TRIGGER sizeTrigger
BEFORE INSERT OR UPDATE
   ON PRODUCTS FOR EACH ROW
BEGIN
   --smalls--
    IF :NEW.product_size = 's' THEN
    :NEW.PRODUCT_SIZE := 'S';
    elsif :NEW.PRODUCT_SIZE = 'S' THEN
       :NEW.product_size := 'S';
     elsif :NEW.PRODUCT_SIZE = 'small'THEN
       :NEW.product_size := 'S';
       elsif :NEW.PRODUCT_SIZE = 'SMALL' THEN
       :NEW.product_size := 'S';
    --MEDIUM--
    elsif :NEW.PRODUCT_SIZE = 'm' THEN
       :NEW.product_size := 'M';
    elsif :NEW.PRODUCT_SIZE = 'm' THEN
       :NEW.product_size := 'M';
    elsif :NEW.PRODUCT_SIZE = 'medium' THEN
       :NEW.product_size := 'M';
        elsif :NEW.PRODUCT_SIZE = 'MEDIUM' THEN
       :NEW.product_size := 'M';
     --large
      elsif :NEW.PRODUCT_SIZE = 'l' THEN
       :NEW.product_size := 'L';
    elsif :NEW.PRODUCT_SIZE = 'L' THEN
       :NEW.product_size := 'L';
    elsif :NEW.PRODUCT_SIZE = 'large' THEN
       :NEW.product_size := 'L';
        elsif :NEW.PRODUCT_SIZE = 'LARGE' THEN
       :NEW.product_size := 'L';
      else
          raise exception_error;        
        END IF;
EXCEPTION
   WHEN exception_error THEN
    DBMS_OUTPUT.PUT_LINE('Size must be "s,m,l,small, medium, large"');
END;

我也会重构你的代码。而不是elsif这样的长级联,你可以拥有:

if upper(:NEW.PRODUCT_SIZE) in ('S', 'SMALL') then :NEW.product_size := 'S';
if upper(:NEW.PRODUCT_SIZE) in ('M', 'MEDIUM') then :NEW.product_size := 'M';
if upper(:NEW.PRODUCT_SIZE) in ('L', 'LARGE') then :NEW.product_size := 'L';

所以最终版本是:

create or replace TRIGGER sizeTrigger
BEFORE INSERT OR UPDATE
   ON PRODUCTS FOR EACH ROW
BEGIN
      if upper(:NEW.PRODUCT_SIZE) in ('S', 'SMALL') then :NEW.product_size := 'S';
      elsif upper(:NEW.PRODUCT_SIZE) in ('M', 'MEDIUM') then :NEW.product_size := 'M';
      elsif upper(:NEW.PRODUCT_SIZE) in ('L', 'LARGE') then :NEW.product_size := 'L';
      else
          raise exception_error;        
      END IF;
EXCEPTION
   WHEN exception_error THEN
    DBMS_OUTPUT.PUT_LINE('Size must be "s,m,l,small, medium, large"');
END;

答案 2 :(得分:0)

以下是工作触发器。我稍微简化了逻辑。

create or replace TRIGGER sizeTrigger
BEFORE INSERT OR UPDATE
   ON PRODUCTS
   FOR EACH ROW
DECLARE
  exception_error       EXCEPTION;
BEGIN
   IF upper(:NEW.product_size)  in ('S','SMALL') THEN :NEW.product_size :='S';
   ELSIF upper(:NEW.product_size)  in ('M','MEDIUM') THEN :NEW.product_size  :='M';
   ELSIF upper(:NEW.product_size)  in ('L','LARGE') THEN :NEW.product_size  :='L';
   ELSE
     raise exception_error; 
   END IF;
EXCEPTION
   WHEN exception_error THEN
    DBMS_OUTPUT.PUT_LINE('Size must be "s,m,l,small, medium, large"');
   RAISE;
END;