Триггер Oracle для предотвращения указанного значения записывается в столбец - PullRequest
0 голосов
/ 03 мая 2018

Я работаю на Oracle 11g 64bit. Скажем, у меня есть таблица с именем «MyTable», я пытаюсь отслеживать столбец с именем «My_Name».

Когда «My_Name» будет изменено на '' (до обновления), я хочу остановить его и изменить «My_Name» на старое значение. Другими словами, '' не является допустимым значением для столбца «My_Name».

Вот что я сделал до сих пор: нет ошибки компиляции, но безрезультатно, я все еще могу записать значение '' в столбец "My_Name".

CREATE OR REPLACE TRIGGER MyTable_tracking
BEFORE INSERT OR UPDATE ON MyDB.MyTable REFERENCING NEW AS newValue OLD AS oldValue
FOR EACH ROW

DECLARE
v_old       VARCHAR(20);
v_new       VARCHAR(20);

BEGIN
  IF INSERTING THEN
    v_new:=:newValue.My_Name; --Trigger checks column 'My_Name' only
  ELSIF UPDATING THEN
    v_old:=:oldValue.My_Name; --Trigger checks column 'My_Name' only
    v_new:=:newValue.My_Name; --Trigger checks column 'My_Name' only
    --IF :newValue.My_Name='' THEN
    IF LENGTH(TRIM(:newValue.My_Name))=0 THEN
      :newValue.My_Name:=:oldValue.My_Name;
    END IF;
  END IF;
END;

Как я могу это сделать?

Ответы [ 2 ]

0 голосов
/ 07 мая 2018

Я исправил свою проблему с помощью следующего кода

IF INSERTING THEN
  v_new:=:newValue.My_Name;
ELSIF UPDATING THEN
  v_old:=:oldValue.My_Name;
  v_new:=:newValue.My_Name;
  --IF :newValue.My_Name='some specified value' THEN --not allow some value
  --IF :newValue.My_Name='' --not working
  IF :newValue.My_Name='' OR :newValue.My_Name IS NULL THEN --not allow '' or null
    :newValue.My_Name:=v_old; --works
    --:newValue.My_Name:=:oldValue.My_Name; --not working, use variable instead
  END IF;
END IF;
0 голосов
/ 03 мая 2018

Нет необходимости в триггере. В Oracle пустая строка '' и null - это одно и то же. Так что просто определите my_name как NOT NULL, и вы не можете поместить в него null или ''.

SQL> create table my_table (id integer primary key, my_name varchar(20) not null);

Table created.

SQL> insert into my_table values (1, 'Arthur');

1 row created.

SQL> update my_table set my_name = '' where id = 1;
update my_table set my_name = '' where id = 1
                    *
ERROR at line 1:
ORA-01407: cannot update ("ARTHUR"."MY_TABLE"."MY_NAME") to NULL

SQL> insert into my_table values (2, '');
insert into my_table values (2, '')
                                *
ERROR at line 1:
ORA-01400: cannot insert NULL into ("ARTHUR"."MY_TABLE"."MY_NAME")

SQL>

Если вы не можете использовать наиболее эффективное решение из-за внешних ограничений (которые я считаю весьма сомнительными), вы можете использовать что-то вроде этого:

create or replace trigger slow_not_null_check
   before insert or update on my_table
   for each row
begin
   if inserting and :new.my_name is null then 
      :new.my_name := 'No NULL allowed';
   end if;

   if updating and :new.my_name is null then 
      :new.my_name := :old.my_name;
   end if;
end;
/ 

Это автоматически преобразует '' в 'No NULL allowed' при вставке и восстанавливает предыдущее значение при обновлении:

insert into my_table values (1, '');
insert into my_table values (2, 'Arthur');

select * from my_table;

ID | MY_NAME        
---+----------------
 1 | No NULL allowed
 2 | Arthur         


update my_table
  set my_name = ''
where id = 2;

select * 
from my_table;


ID | MY_NAME        
---+----------------
 1 | No NULL allowed
 2 | Arthur         
...