我有一个Users表,每个User都有一个标识符,一个名称和一些其他字段。 我需要在插入或更新后检查是否有其他同名用户,所以我做了这个触发器:
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检查,因此它始终失败,因为它找到具有相同名称的同一用户。 为什么会这样?谢谢
答案 0 :(得分: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
但是在评论中建议您使用主键,但我的答案是让您理解触发器