2016-12-11 25 views
-4

我正在尝试创建一个触发器,允许输入具有小 - 大尺寸的衣物,但触发器将根据插入将大小更改为SM或L 。创建更新触发器时出现变量名称错误

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

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; 
+1

摆脱列定义周围的所有双引号。 – OldProgrammer

回答

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; 
+0

嘿,这个你能解释我做错了什么吗?我知道我有双'::' – nagel9

+0

1)没有为每一行 – arturro

+0

2)在put_line调用中没有关闭字符串3):: NEW而不是:NEW – arturro

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; 
+0

我认为这有帮助,但我仍然得到坏绑定变量错误(PLS-00049)和编译器错误ORA-04082:新的旧引用不允许在表级别触发器 – nagel9

+0

@ nagel9现在尝试'为每行'添加 – Kacper

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;