2016-12-11 40 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;