2016-01-10 73 views
1

我有一個Users表,每個用戶都有一個標識符,一個名稱和一些其他字段。 我需要檢查是否有插入或更新後具有相同名稱的另一個用戶,所以我做了這個觸發:檢查每個表對象是否具有不同的名稱

CREATE OR REPLACE TRIGGER user_name 
    BEFORE 
    INSERT OR UPDATE 
    ON Users 
    FOR EACH ROW 
DECLARE 
    count INTEGER; 
BEGIN 
SELECT COUNT(*) INTO count FROM Users WHERE name = :new.name AND idUser <> :new.idUser; 
    IF count > 0 
    THEN raise_application_error(-20007, 'There is already another user with the same name'); 
    END IF; 
END; 

似乎插入新的用戶何時工作,但是當我更新它們它不,它看起來像「忽略」idUser檢查,因此它總是失敗,因爲它找到了同名用戶。 這是怎麼回事?謝謝

+3

爲什麼你不使用「唯一」約束? – Mat

+1

'在用戶(名稱)上創建唯一索引uk_user_name;'解決您的所有問題 –

+0

是的,它適用於唯一的約束/索引,但我想知道爲什麼它不以這種方式工作。 – JulioAGM

回答

1

在觸發器中,有3個狀態,因爲您知道插入更新和刪除,更新狀態中有新值和舊值,我的意思是當您更新列時,您將用新值替換舊值在觸發您可以使用舊的和列的新值。請在上面的例子檢查這個例子

CREATE or REPLACE TRIGGER test001 
    AFTER INSERT OR UPDATE OR DELETE ON tabletest001 


DECLARE 
     Operation  NUMBER; 
     CustomerCode CHAR(10 BYTE); 
BEGIN 


IF INSERTING THEN 
    Operation := 1; 
    CustomerCode := :new.field1; 
END IF; 

IF UPDATING THEN 
    Operation := 2; 
    CustomerCode := :old.field1; 
END IF;  

// DO SOMETHING ... 

EXCEPTION 
    WHEN OTHERS THEN ErrorCode := SQLCODE; 

END; 
/

,在更新狀態我用old.value之列,所以在你的榜樣,你應檢查舊值不新,請嘗試

if updating then 

SELECT COUNT(*) INTO count FROM Users WHERE name = :old.name AND idUser <> :old.idUser; 
    IF count > 0 
    THEN raise_application_error(-20007, 'There is already another user with the same name'); 

end if 

然而在評論中提醒你使用主鍵,但是我的答案是讓你對觸發器有所瞭解

相關問題