Oracle触发器阻止指定值写入列

时间:2018-05-03 09:07:41

标签: oracle11g database-trigger

我正在使用Oracle 11g 64位。 假设我有一个名为“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 :(得分:0)

无需触发器。在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         

答案 1 :(得分:0)

我在代码

后解决了我的问题
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;