sql 触发器上的列 (Oracle)

Columns on sql Triggers (Oracle)

我想如果当插入 'zone' 为 null 时,触发器将被触发并将区域值从 'null' 更改为 'sin',我认为问题出在 if .

CREATE OR REPLACE TRIGGER ZONA_JUGADOR
    BEFORE INSERT ON EQUIPOS FOR EACH ROW
BEGIN
    IF :NEW.ZONA = NULL THEN
    :NEW.ZONA:='SIN';
    END IF;

END;

我做的插句:

VALUES ('eq47','01826247G','Miranda',NULL); 

问题出在IFNULL 不是 "equal" 的东西,所以你不能使用

if :new.zona = null 

但是

if :new.zona IS NULL

无论如何,也许您更愿意使用 NVL 函数:

SQL> create table equipos (id varchar2(10), zona varchar2(10));

Table created.

SQL> create or replace trigger zona_jugador
  2    before insert on equipos
  3    for each row
  4  begin
  5    :new.zona := nvl(:new.zona, 'SIN');
  6  end;
  7  /

Trigger created.

SQL> insert into equipos(id, zona) values ('ba12', 'zona');

1 row created.

SQL> insert into equipos(id, zona) values ('eq47', null);

1 row created.

SQL> select * From equipos;

ID         ZONA
---------- ----------
ba12       zona
eq47       SIN

SQL>

另一种方法是使用 when 子句将 null 检查作为触发器定义(而不是主体)的一部分:

create or replace trigger zona_jugador
  before insert on equipos
  for each row
  when (new.zona is null)
begin
  :new.zona := 'SIN';
end;
/

请注意 when 指的是 new 而不是 :new。正如@Littlefoot 和 shown in the documentation.

所解释的那样,它仍然是 is null 而不是 = null

结果是一样的,但在某些情况下,这可能会更好,因为触发器不必在无事可做时触发,从而节省 SQL 和 PL/SQL 之间的上下文切换.您可能需要对大量数据进行一些相当密集的操作才能真正注意到差异,但仍然,所有这些都会加起来。

db<>fiddle 借用@Littlefoot 的设置。