所以我有两张桌子:
CREATE TABLE SALE(
OID_PA NUMBER(*,0) PRIMARY KEY,
Amount INTEGER NOT NULL,
Delivery_DATE DATE NOT NULL,
OID_V NUMBER(*,0) NOT NULL,
CONSTRAINT "AMOUNTCHECK" CHECK(Amount >=0),
FOREIGN KEY (OID_V) REFERENCES TICKET(OID_V));
和
CREATE TABLE PRODUCT
( Code NUMBER(*,0) PRIMARY KEY,
Stock INTEGER NOT NULL,
Price NUMBER(4,2) NOT NULL,
Production_Cost NUMBER NOT NULL,
Model VARCHAR2(50) NOT NULL,
TipoMueble VARCHAR2(50) NOT NULL,
TipoMaterial VARCHAR2(50) NOT NULL,
OID_PA NUMBER(*,0) NOT NULL,
CONSTRAINT "TipoMueble" CHECK(TipoMueble IN
('Canteado','Complementos','Glaciar',
'GrupoDiseño','Tiradores','Vitrinas')),
CONSTRAINT "TipoMaterial" CHECK(TipoMaterial IN ('Aluminio','Lacados',
'Polilaminado','Madera','Cristal','Chapa','Granito','Formica',
'Aglomerado','Marmol','Elementos de ferreteria')),
CONSTRAINT "StockNegativo" CHECK(Stock >=0),
CONSTRAINT "Precio" CHECK(Price>=0),
CONSTRAINT "CosteProduccion" CHECK (Production_cost>=0),
FOREIGN KEY (OID_PA) REFERENCES PAQUETE(OID_PA));
现在我想创建一个触发器,我修改属性" Amount"在表格" SALE"然后它应该检查表" PRODUCT"。 如果" stock" (在PRODUCT中)小于金额(在SALE中)然后
RAISE_APPLICATION_ERROR(-20003, 'Not enough stock');
但我不知道如何在两张桌子上同时进行触发检查。 现在我的代码现在看起来很像,它也有一些我不确定如何解决的错误。
CREATE OR REPLACE TRIGGER TR_ENOUGH_STOCK
AFTER INSERT OR UPDATE OF Amount ON SALE
BEGIN
SELECT a.Amount, b.Stock
FROM ( SALE a inner join PRODUCT b on (a.Code = b.Code))
IF b.Stock < a.Amount THEN
RAISE APPLICATION ERROR(-20003, 'Not enough stock');
END IF;
END;
/
我收到以下错误:
Error(209,5): PL/SQL: SQL Statement ignored
Error(212,5): PL/SQL: ORA-00933: SQL command not properly ended
Error(214,9): PLS-00103: Encountered the symbol "IF" when expecting one of
the following: ; <an identifier> <a double-quoted delimited-identifier>
答案 0 :(得分:0)
这是一个如何做到这一点的例子。
创建表格&amp;触发器:
SQL> create table sale (oid_pa number, amount number);
Table created.
SQL> create table product (code number, stock number, oid_pa number);
Table created.
SQL>
SQL> create or replace trigger trg_biu_stock
2 before insert or update
3 on sale
4 for each row
5 declare
6 l_stock product.stock%type;
7 begin
8 select stock into l_stock
9 from product
10 where oid_pa = :new.oid_pa;
11
12 if :new.amount > l_stock then
13 raise_application_error(-20000, 'Not enough stock');
14 end if;
15 end;
16 /
Trigger created.
SQL>
将样本记录插入PRODUCT表:
SQL> insert into product values (1, 100, 10);
1 row created.
SQL> insert into product values (2, 50, 20);
1 row created.
SQL> select * From product;
CODE STOCK OID_PA
---------- ---------- ----------
1 100 10
2 50 20
SQL>
让我们测试一下:
SQL> -- 90 is less OID_PA = 10 stock value (which is 100)
SQL> insert into sale values (10, 90);
1 row created.
SQL> -- let's try to update it to a value larger than stock value:
SQL> update sale set amount = 200 where oid_pa = 10;
update sale set amount = 200 where oid_pa = 10
*
ERROR at line 1:
ORA-20000: Not enough stock
ORA-06512: at "HR.TRG_BIU_STOCK", line 9
ORA-04088: error during execution of trigger 'HR.TRG_BIU_STOCK'
SQL> -- how about a value which doesn't exceed the stock value?
SQL> update sale set amount = 5 where oid_pa = 10;
1 row updated.
SQL> select * From sale;
OID_PA AMOUNT
---------- ----------
10 5
SQL>
从你的尝试开始:除了触发器代码语法错误之外,它无论如何都无法工作,因为你无法引用表触发器是基于因为它现在正在被更改,即它是变异。在这种情况下,Oracle会引发错误(请参阅下面的示例)。正确的方法是使用:new或:old来引用该表的列,就像我一样(参见上面的例子)。
SQL> create or replace trigger trg_biu_stock
2 before insert or update
3 on sale
4 for each row
5 declare
6 l_stock product.stock%type;
7 begin
8 select p.stock into l_stock
9 from product p
10 join sale s
11 on s.oid_pa = p.oid_pa
12 where p.oid_pa = :new.oid_pa;
13
14 if :new.amount > l_stock then
15 raise_application_error(-20000, 'Not enough stock');
16 end if;
17 end;
18 /
Trigger created.
SQL> update sale set amount = 50 where oid_pa = 10;
update sale set amount = 50 where oid_pa = 10
*
ERROR at line 1:
ORA-04091: table HR.SALE is mutating, trigger/function may not see it
ORA-06512: at "HR.TRG_BIU_STOCK", line 4
ORA-04088: error during execution of trigger 'HR.TRG_BIU_STOCK'
SQL>