перед INSERT или Update триггером plsql

Может ли кто-нибудь помочь мне написать триггер, чтобы запретить определенную запись в таблицу (например, местоположение = «Чикаго» не разрешено). Схема таблицы выглядит следующим образом: отдел (номер отдела, имя отдела, местоположение). Я использую oracle 10g.


person wantobegeek    schedule 24.08.2009    source источник
comment
Этого легко добиться с помощью хранимой процедуры, но я не уверен, что поместил бы ее туда (если только у вас нет разработчиков, работающих непосредственно с вашей базой данных, и вы хотите ограничить их, что маловероятно), такие виды бизнеса ограничивают обычно выполняются в коде, на много уровней выше базы данных. Конечно, я ничего не знаю о вашем коде или вашем дизайне, просто комментарий...   -  person Kobi    schedule 24.08.2009


Ответы (1)


Вы можете легко делать то, что хотите, с помощью CHECK CONSTRAINT в своей колонке.

ALTER TABLE T
ADD CONSTRAINT constraint_name CHECK (location <> 'chicago') [DISABLE];

Ключевое слово DISABLE является необязательным. Если вы создадите проверочное ограничение с помощью ключевого слова DISABLE, ограничение будет создано, но условие не будет выполняться.

Состояния ограничений

  • ВКЛЮЧИТЬ – убедитесь, что все входящие данные соответствуют ограничениям.
  • ОТКЛЮЧИТЬ – разрешить входящие данные независимо от того, соответствуют ли они ограничениям.
  • ПРОВЕРКА – убедитесь, что существующие данные соответствуют ограничениям.
  • NOVALIDATE — существующие данные не обязательно должны соответствовать ограничению.

Они могут использоваться в сочетании

ВКЛЮЧИТЬ { [по умолчанию] ПРОВЕРИТЬ | НОВАЯ ДАТА }

ОТКЛЮЧИТЬ { ПРОВЕРИТЬ |[по умолчанию] НОВАЛИДАТЬ }

  • ENABLE VALIDATE — это то же самое, что и ENABLE.

  • ENABLE NOVALIDATE означает, что ограничение проверено, но оно не обязательно должно быть истинным для всех строк. это возобновит проверку ограничений для отключенных ограничений без предварительной проверки всех данных в таблице.

  • DISABLE NOVALIDATE — это то же самое, что и DISABLE.

  • DISABLE VALIDATE отключает ограничение, удаляет индекс ограничения и запрещает любое изменение ограниченных столбцов. для ограничения UNIQUE это позволяет загружать данные из неразделенной таблицы в многораздельную таблицу с помощью предложения ALTER TABLE.. EXCHANGE PARTITION.

Вот пример триггера BEFORE INSERT. Однако лучше создать ограничения на вашу схему или реализовать CUSTOM_INSERT PROCEDURE, чтобы отфильтровать ее. Вот хорошая статья о целостности данных — ограничениях и триггерах.

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

Пример триггера (считайте его плохой идеей для фильтрации ввода):

CREATE TRIGGER myTrigger 
BEFORE INSERT
ON table
REFERENCING NEW AS New
FOR EACH ROW
   BEGIN
   IF (New.location = 'chicago') THEN
       RAISE cError;    
EXCEPTION
WHEN cError THEN
      RAISE_APPLICATION_EXCEPTION(-20001,'Chicago is not allowed');
END;
person Svetlozar Angelov    schedule 24.08.2009
comment
Вместо DELETE должно быть RAISE_APPLICATION_ERROR(-20000,'Нет Чикаго, пожалуйста!'); - person jva; 24.08.2009
comment
Весь триггер вообще не нужен. И в моем примере (плохом) триггер после... - person Svetlozar Angelov; 24.08.2009
comment
Недостатком триггера является то, что вам придется провалить оператор. С проверочным ограничением у разработчика есть возможность использовать предложение LOG ERRORS, чтобы корректные данные были вставлены, а недопустимые данные были помещены в таблицу исключений. Очень полезно для массовой загрузки данных. - person Gary Myers; 24.08.2009
comment
Стоит добавить, что существует функция NOVALIDATE для проверки ограничений, так что ограничение применяется для новых вставок, но существующие «недействительные» данные могут оставаться в таблице (например, если вы закрыли офис в Чикаго, исторические данные могут остаться, но вы не получите никаких новых данных) - person Gary Myers; 24.08.2009
comment
Хорошее замечание! ENABLE NOVALIDATE означает, что ограничение проверено, но оно не обязательно должно быть истинным для всех строк. это возобновит проверку ограничений для отключенных ограничений без предварительной проверки всех данных в таблице. - person Svetlozar Angelov; 24.08.2009