Триггер Creationg для ограничения значения NULL для новой записи адреса - PullRequest
0 голосов
/ 01 октября 2019

Я попытался создать триггер, который напоминает пользователям избегать нулевого значения в address1, если роль - это Компания. Вот где я закончил:

CREATE OR REPLACE TRIGGER "SCHEMA"."ADDRESS_VALUE"                          
BEFORE INSERT OR UPDATE ON "SCHEMA"."TABLE1"
FOR EACH ROW
DECLARE
  ADDRESS TABLE1.ADDRESS1%TYPE;   
  V_CNT NUMBER; 
BEGIN
  ADDRESS := :NEW.ADDRESS1;
  IF :OLD.ADDRESS1 = ADDRESS THEN
    RETURN;
  END IF;

  SELECT COUNT(1)
    INTO V_CNT    
    FROM SCHEMA.TABLE2 
   WHERE ROLE = 'COMPANY';

  IF V_CNT > 0 THEN 
    RAISE_APPLICATION_ERROR(-20101,' ADDRESS IS MANDATORY');              
  END IF;
END;

Кажется, что это работает правильно и выдает сообщение «адрес обязателен», если пользователи пытаются оставить его пустым, но сообщение продолжает поступать, даже если они пытаютсядобавить что-то в address1. Он застрял там и не позволит продолжить, даже если обязательное поле <> пусто. Что не так?

Не могли бы вы помочь мне с этим раздражающим вопросом. Спасибо.

Используется Oracle 11g.

С уважением, Почти первый в истории триггер

1 Ответ

0 голосов
/ 01 октября 2019

Ваш триггер имеет несколько проблем. Кажется, у вас есть условный ненулевой столбец, в лучшем случае плохой дизайн. Поддержка роли «КОМПАНИЯ» определяет, может ли address1 быть нулевым. Если роль вообще существует, она не обязательно должна быть связана с обрабатываемой строкой, тогда Address1 не может быть нулевым для любой строки. Итак, что вы будете делать с существующими пустыми строками address1 при первоначальном добавлении роли. Есть проблема несуществующей старой записи для вставок. Вы проверяете, изменился ли address1;Я предполагаю, что вы можете утверждать, что переходная форма, не существующая к существующим технически, квалифицируется как измененная. Это будет работать, но не рекомендуется. Чтобы исправить, мы избавимся от этого полностью. Наконец, ваша основная жалоба на то, что исключение выдается, даже если известно, что адрес1 не равен нулю. Это связано с тем, что вы даже не тестировали его содержимое на null. Вы сгенерировали исключение, если существует роль «КОМПАНИЯ». По сути, триггер говорит, что «если в таблице 2 существует роль« КОМПАНИЯ », не разрешайте вставки в таблицу 1 или обновления существующих значений address1 в таблице 1». Попробуйте следующее:

CREATE OR REPLACE TRIGGER "SCHEMA"."ADDRESS_VALUE"                          
BEFORE INSERT 
    OR UPDATE of address1 
    ON "SCHEMA"."TABLE1"
FOR EACH ROW
DECLARE 
  V_CNT NUMBER; 
BEGIN
  if :new.address1 is null
  then 
      SELECT COUNT(1)
        INTO V_CNT    
        FROM SCHEMA.TABLE2 
       WHERE ROLE = 'COMPANY';

      IF V_CNT > 0 THEN 
        RAISE_APPLICATION_ERROR(-20101,' ADDRESS IS MANDATORY');              
      END IF;
  end if;
END; 

Что изменилось? Ну, во-первых, обратите внимание на изменение в заголовке триггера, в частности в спецификации UPDATE. Ревизия устраняет необходимость проверки, если она изменилась при обновлении. Если это не изменилось, триггер не срабатывает. Во-вторых, существование роли проверяется только в том случае, если новый адрес1 является нулевым, если роль не равна нулю, роль существующая или нет не имеет значения. Наконец, существует потенциальная проблема, связанная с тем, что строка не связана с ролью «КОМПАНИЯ», но не имеет допустимой нулевой способности, поскольку она существует. Нам нужно определить связь между таблицами и DDL, чтобы они оба прокомментировали это.

...