Oracle 插入触发器前的行级别

Oracle 插入触发器前的行级别,oracle,plsql,triggers,sql-insert,Oracle,Plsql,Triggers,Sql Insert,我正在为product表创建行级触发器,该触发器将在对产品执行插入操作之前触发。如果产品类型在product\u type\u master表中可用,此触发器将在产品表中插入新记录 SQL> select * from Product_master; ID NAME PRICE TYPE ---------- ---------- ---------- -------------------- 1 keyboard 3

我正在为
product
表创建行级触发器,该触发器将在对产品执行插入操作之前触发。如果产品类型在
product\u type\u master
表中可用,此触发器将在产品表中插入新记录

SQL> select * from Product_master;

        ID NAME            PRICE TYPE
---------- ---------- ---------- --------------------
        1 keyboard         3077 ip
        2 monitor          9847 op
        3 usb               807 sto

 SQL> select * from type_master;

        NO TYPE
---------- --------------------
        1 in
        2 op
        3 sto
因此,条件是,如果新的插入类型等于type_主表中给定的类型,则只应插入它,否则不应插入

我创建了一个:

create or replace trigger ins_trigger
   2  before insert on product_master for each row
   3  begin
   4      if(:new.type == type.type_master)then
   5          insert into product_master values('id',name,'price',type);
   6      end if;
   7  end;
   8  /

   Warning: Trigger created with compilation errors.

无法通过
type.type\u master
从表
type\u master
访问列
type
。你必须选择它

如果对主表创建外键约束,则根本不需要触发器:

ALTER TABLE product\U master添加约束 产品\主控\类型\主控\ fk外键(类型)引用 类型\主控(类型)


您不必在触发器中执行insert语句。触发器是从insert语句触发的。

我将创建如下表:

create table product_types
( type_id       integer generated always as identity constraint product_type_pk primary key
, type_name     varchar2(30) not null constraint type_name_uk unique );

create table products
( prod_id       integer generated always as identity constraint product_pk primary key
, prod_name     varchar2(30) not null constraint product_name_uk unique
, prod_price    number(10,2)
, prod_type_id  constraint product_type_fk references product_types(type_id) );
以便您不能输入无效的产品类型:

insert into products (prod_name, prod_price, prod_type_id)
values ('Cheese', 123.45, 1);

ERROR at line 1:
ORA-02291: integrity constraint (WILLIAM.PRODUCT_TYPE_FK) violated - parent key not found
但是,为了演示触发器语法(因为不需要使用此触发器),如果我必须编写一个触发器,它将是:

create or replace trigger really_should_be_a_foreign_key
    before insert or update on products
    for each row when (new.prod_type_id is not null)
declare
    l_parent_type_count number;
begin
    select count(*) into l_parent_type_count
    from   product_types t
    where  t.type_id = :new.prod_type_id;
    
    if l_parent_type_count = 0 then
        raise_application_error
        ( -20000
        , 'Product type "'||:new.prod_type_id||'" is not defined.' ); 
    end if;
end really_should_be_a_foreign_key;
然后,尝试输入无效的产品类型失败,并显示来自触发器的错误消息:

第1行出现
错误:
ORA-20000:未定义产品类型“1”。
ORA-06512:“威廉,你真的应该是外键吗”,第9行
ORA-04088:执行触发器“WILLIAM.真的应该是外键”时出错

其他人已经提到了你的方法,但我没有看到有人提到

警告:使用编译错误创建触发器

当您收到此消息时,应立即使用“显示错误”进行后续操作


当你这样做的时候,你会发现“==”是无效的。检查你的,2.7.5.2.1算术比较

A在这里会做得更好。嘿,你能给我解释一下触发器吗。我在插入或更新之前做了
,而不仅仅是在插入之前
,因为你也想防止使用无效值的更新
when(new.prod\u type\u id不为null)
因此它仅在存在实际类型id时执行检查(假设该类型id是可选列)
如果
语法没有括号,并且相等运算符是
=
,而不是
=
(与SQL相同)。看见