Triggers 针对特定更新情况在SQL中修改表

Triggers 针对特定更新情况在SQL中修改表,triggers,oracle10g,Triggers,Oracle10g,我已经为表股票创建了一个触发器 该表的架构如下所示: create table stock(item_code varchar2(2) primary key, p_qty number(2),s_qty number(2)); CREATE OR REPLACE TRIGGER TR_STOCK BEFORE UPDATE OF S_QTY ON STOCK FOR EACH ROW DECLARE V_P STOCK.P_QTY%TYPE; V_S STOCK.S_QTY%

我已经为表股票创建了一个触发器

该表的架构如下所示:

create table stock(item_code varchar2(2) primary key, p_qty number(2),s_qty number(2));
CREATE OR REPLACE TRIGGER TR_STOCK BEFORE UPDATE OF S_QTY ON STOCK FOR EACH ROW
DECLARE
    V_P STOCK.P_QTY%TYPE;
    V_S STOCK.S_QTY%TYPE;
    V_I VARCHAR2(2);
BEGIN
    V_S:=:NEW.S_QTY;
    V_I:=:NEW.ITEM_CODE;
    SELECT P_QTY INTO V_P FROM STOCK WHERE ITEM_CODE=V_I;
    IF V_S>V_P THEN
        RAISE_APPLICATION_ERROR(-20400,'SOLD QTY CANNOT EXCEED PURCHASED QTY...');
    END IF;
END;
/
触发条件如下:

create table stock(item_code varchar2(2) primary key, p_qty number(2),s_qty number(2));
CREATE OR REPLACE TRIGGER TR_STOCK BEFORE UPDATE OF S_QTY ON STOCK FOR EACH ROW
DECLARE
    V_P STOCK.P_QTY%TYPE;
    V_S STOCK.S_QTY%TYPE;
    V_I VARCHAR2(2);
BEGIN
    V_S:=:NEW.S_QTY;
    V_I:=:NEW.ITEM_CODE;
    SELECT P_QTY INTO V_P FROM STOCK WHERE ITEM_CODE=V_I;
    IF V_S>V_P THEN
        RAISE_APPLICATION_ERROR(-20400,'SOLD QTY CANNOT EXCEED PURCHASED QTY...');
    END IF;
END;
/
现在,每次我执行更新查询时,它都会说表正在发生变化,并标记以下错误:

update stock set s_qty=2 where item_code='i4'
       *
ERROR at line 1:
ORA-04091: table HR.STOCK is mutating, trigger/function may not see it
ORA-06512: at "HR.TR_STOCK", line 8
ORA-04088: error during execution of trigger 'HR.TR_STOCK'

关于这个特定问题有什么帮助吗?

不需要查询
库存
表。只需直接比较
:NEW.P_数量
:NEW.S_数量
字段

CREATE OR REPLACE TRIGGER TR_STOCK BEFORE UPDATE OF S_QTY ON STOCK FOR EACH ROW
DECLARE
BEGIN
    IF :new.s_qty > :new.p_qty THEN
        RAISE_APPLICATION_ERROR(-20400,'SOLD QTY CANNOT EXCEED PURCHASED QTY...');
    END IF;
END;
/

无需查询
库存
表。只需直接比较
:NEW.P_数量
:NEW.S_数量
字段

CREATE OR REPLACE TRIGGER TR_STOCK BEFORE UPDATE OF S_QTY ON STOCK FOR EACH ROW
DECLARE
BEGIN
    IF :new.s_qty > :new.p_qty THEN
        RAISE_APPLICATION_ERROR(-20400,'SOLD QTY CANNOT EXCEED PURCHASED QTY...');
    END IF;
END;
/

<>你真的应该考虑使用一个数据库约束来实现这个逻辑,在这种情况下,你根本不需要触发器。p>
ALTER TABLE hr.stock 
ADD CONSTRAINT stock_ck1
CHECK (
  s_qty <= p_qty
)
ALTER表hr.stock
添加约束库存_ck1
检查(

SyQTy

你确实应该考虑使用数据库约束来实现这个逻辑,在这种情况下,你根本不需要触发器。

ALTER TABLE hr.stock 
ADD CONSTRAINT stock_ck1
CHECK (
  s_qty <= p_qty
)
ALTER表hr.stock
添加约束库存_ck1
检查(

您不能从触发器中更新的表中选择。这可能表明您的数据模型中存在缺陷…但似乎不需要执行类似操作。为什么不使用
if
语句。您不能从触发器中更新的表中选择。这可能表明您的数据中存在缺陷模型…似乎没有必要这样做。为什么不使用
if
语句呢。