2016-01-10 1 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

Почему вы не используете ограничение 'unique'? – 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 

однако, как и в комментариях, вы должны использовать первичный ключ, однако мой ответ заключается в том, чтобы дать вам понять триггеры

Смежные вопросы