请各位帮我看一下这个触发器哪里写错了,该怎么改现在有三张表,结构如下---------------------采购进货/采购退货表-----------------------
CREATE TABLE WSSSELLERINOUT(
SIOID CHAR(14),
SIODATE DATE,
PRVID CHAR(4),
SIONEEDPAY NUMBER(10),
SIOPAID NUMBER(10),
SIOOWE NUMBER(10),
OPRTID CHAR(3),
STAID CHAR(3),
SISTATUS CHAR(1),
SIOTYPE CHAR(1),--这个字段代表是进货还是退货
CONSTRAINTS SELLERINOUT_SIOID_PK PRIMARY KEY(SIOID)
);
---------------------采购进货/采购退货表详细-----------------------
CREATE TABLE WSSSELLERINOUTDETAIL(
SIOID CHAR(14),--通过外键关联到采购进货/采购退货总表
MID CHAR(5),
STOID CHAR(2),
MAMOUNT NUMBER(3),
PRICE NUMBER(6),
SUMPRICE NUMBER(10),
CONSTRAINTS SELLERINOUTDETAIL_SIOMSTO_PK PRIMARY KEY(SIOID, MID, STOID)
);
-----------------------库存信息--------------------------
CREATE TABLE WSSSTORAGE(
MID CHAR(5),
STOAMOUNT NUMBER(3),
SELLSUM NUMBER(3),
PREINPRICE NUMBER(6),
AVGINPRICE NUMBER(6),
SELLSUMPRICE NUMBER(10),
STOSUMPRICE NUMBER(10),
STOID CHAR(2),
CONSTRAINTS STORAGE_MSTO_PK PRIMARY KEY(MID, STOID)
);各个外键关联的语句没有放上来...我想通过触发器实现在进货退货详细表中添加产品时在库存信息中也进行相应的修改,写了这么一个触发器,可是总是显示触发器无效未通过确认,不明白应该怎么改
--定义进货退货时在详单上插入数据后同步更新库存的触发器
CREATE OR REPLACE TRIGGER WSSSIOD_WSSSTO
AFTER INSERT ON WSSSELLERINOUTDETAIL
FOR EACH ROW
DECLARE
V_INOUT WSSSELLERINOUT.SIOTYPE%TYPE;
BEGIN
--首先判断是进货还是退货
SELECT IO.SIOTYPE
INTO V_INOUT
FROM WSSSELLERINOUT IO
WHERE IO.SIOID = :NEW.SIOID;
IF V_INOUT = '1' THEN
--进货时,若库存中有这件商品则库存量增加
UPDATE WSSSTORAGE STO
SET STO.STOAMOUNT = STO.STOAMOUNT + :NEW.MAMOUNT
WHERE STO.MID = :NEW.MID;
--如果库存里还没有这件商品就新加一条记录
IF SQL%NOTFOUND THEN
INSERT INTO WSSSTORAGE
VALUES(:NEW.MID,:NEW.MAMOUNT,0,:NEW.PRICE,0,0,0,:NEW.STOID);
END IF;
ELSIF V_INOUT = '0' THEN
--退货时不可能存在找不到退货商品,退货时库存减少
UPDATE WSSSTORAGE STO
SET STO.STOAMOUNT = STO.STOAMOUNT - :NEW.MAMOUNT;
END IF;
END;
CREATE TABLE WSSSELLERINOUT(
SIOID CHAR(14),
SIODATE DATE,
PRVID CHAR(4),
SIONEEDPAY NUMBER(10),
SIOPAID NUMBER(10),
SIOOWE NUMBER(10),
OPRTID CHAR(3),
STAID CHAR(3),
SISTATUS CHAR(1),
SIOTYPE CHAR(1),--这个字段代表是进货还是退货
CONSTRAINTS SELLERINOUT_SIOID_PK PRIMARY KEY(SIOID)
);
---------------------采购进货/采购退货表详细-----------------------
CREATE TABLE WSSSELLERINOUTDETAIL(
SIOID CHAR(14),--通过外键关联到采购进货/采购退货总表
MID CHAR(5),
STOID CHAR(2),
MAMOUNT NUMBER(3),
PRICE NUMBER(6),
SUMPRICE NUMBER(10),
CONSTRAINTS SELLERINOUTDETAIL_SIOMSTO_PK PRIMARY KEY(SIOID, MID, STOID)
);
-----------------------库存信息--------------------------
CREATE TABLE WSSSTORAGE(
MID CHAR(5),
STOAMOUNT NUMBER(3),
SELLSUM NUMBER(3),
PREINPRICE NUMBER(6),
AVGINPRICE NUMBER(6),
SELLSUMPRICE NUMBER(10),
STOSUMPRICE NUMBER(10),
STOID CHAR(2),
CONSTRAINTS STORAGE_MSTO_PK PRIMARY KEY(MID, STOID)
);各个外键关联的语句没有放上来...我想通过触发器实现在进货退货详细表中添加产品时在库存信息中也进行相应的修改,写了这么一个触发器,可是总是显示触发器无效未通过确认,不明白应该怎么改
--定义进货退货时在详单上插入数据后同步更新库存的触发器
CREATE OR REPLACE TRIGGER WSSSIOD_WSSSTO
AFTER INSERT ON WSSSELLERINOUTDETAIL
FOR EACH ROW
DECLARE
V_INOUT WSSSELLERINOUT.SIOTYPE%TYPE;
BEGIN
--首先判断是进货还是退货
SELECT IO.SIOTYPE
INTO V_INOUT
FROM WSSSELLERINOUT IO
WHERE IO.SIOID = :NEW.SIOID;
IF V_INOUT = '1' THEN
--进货时,若库存中有这件商品则库存量增加
UPDATE WSSSTORAGE STO
SET STO.STOAMOUNT = STO.STOAMOUNT + :NEW.MAMOUNT
WHERE STO.MID = :NEW.MID;
--如果库存里还没有这件商品就新加一条记录
IF SQL%NOTFOUND THEN
INSERT INTO WSSSTORAGE
VALUES(:NEW.MID,:NEW.MAMOUNT,0,:NEW.PRICE,0,0,0,:NEW.STOID);
END IF;
ELSIF V_INOUT = '0' THEN
--退货时不可能存在找不到退货商品,退货时库存减少
UPDATE WSSSTORAGE STO
SET STO.STOAMOUNT = STO.STOAMOUNT - :NEW.MAMOUNT;
END IF;
END;
解决方案 »
- sequence为什么程序里面调用nextval之后。。再pl/sql里用curral查不到更新后的当前值。。
- 救命呀!谁知道如何在Mac下安装Oracle?
- Oracle 10G 启动了,但不能用,只占了12M内存
- 急,imp怪异问题,请高手协助
- oracle 9i 同时锁表???
- 在线等:哪位高手能告诉我--如何在oracle 9i中根据表中的帐号随机生成密码??
- 看如下电台管理的详细数据库设计,如何扩展它去支持历史数据的多版本操作呢?
- 生成一批可以控制的帐号
- oracle 数据库启动问题
- Database link的语法
- 请问这个触发器怎么写
- oracle数据库imp两个用户的数据???
exception
when others then
dbms_output.put_line(sqlcode||' '||sqlerrm);插入数据后,看看输出的错误代码和信息
应该没有语法错误,最可能出现错误的地方在这里
SELECT IO.SIOTYPE
INTO V_INOUT
FROM WSSSELLERINOUT IO
WHERE IO.SIOID = :NEW.SIOID;
检查下时候能返回有且只有一条数据
要考虑返回多条记录或没有符合条件的记录的情况,这样会导致异常
原因可能是wildwave所说,WSSSELLERINOUT存在多个SIOID 导致,可能是你的测试数据存在重复,导致select
into 出现多值出错。
INTO V_INOUT
FROM WSSSELLERINOUT IO
WHERE IO.SIOID = :NEW.SIOID;
改成
SELECT nvl(max(IO.SIOTYPE),0)
INTO V_INOUT
FROM WSSSELLERINOUT IO
WHERE IO.SIOID = :NEW.SIOID;
能解决问题
不过你应该考虑下业务逻辑
如果这个查询语句没有返回记录或返回多条记录该怎么处理