这个问题再网上有很多答案,也测试用的,仍没有解决问题;
需求: 对库存表的增删改触发执行物资主表单价的更新;
条件: 1.根据先进先出,这个单价是最新进库的单价
2.这个单价还的是保证其数量不为0 的情况下;
create or replace trigger kcdanjia_trigger
after update or insert or delete on gmkucunxinxi
for each row
--库存先进先出更新物资主表单价DECLARE
danjias number(14,2);
begin
--提取先进的并且数量大于0的库存物资单价
select g.danjia into danjias
from gmkucunxinxi g
where g.kucunid = (select min(kucunid)
from gmkucunxinxi
where wuzimingcheng = :new.wuzimingcheng
and shuliang > 0); dbms_output.put_line(danjias);
dbms_output.put_line(:new.wuzimingcheng); --把单价更新到物资主表
update GMWUZIXINXI set danjia = danjias where WUZI_ID = :new.wuzimingcheng ;end;主要报错:gmkucunxinxi 表发生变化,触发器/函数不能读它;后期也根据网上说的:你这报错是因为变异表的问题,触发器尝试读取正在发生改变的表时都会报这个错误。以及:new,:old的用法问题 : insert是插入数据,所以只会有new,
delete是删除数据,所以只会有old,
update是更新数据,所以new和old都有就改成这种形式的:
DECLARE
danjias number(14,2);
ids number(10);
wuzimingchengs number(10);
begin
if inserting then
wuzimingchengs := :new.wuzimingcheng;
dbms_output.put_line(wuzimingchengs);
select kucunid into ids
from gmkucunxinxi
where wuzimingcheng = 318
and shuliang > 0 and rownum=1; dbms_output.put_line(ids);
end if;含有inserting,updating,delete判断的形式,结果也是一样;
现在我也尝试了变 行级触发器 为 语句级触发器,但关键我还必行的用到 库存表更新时的数据;
但是 new old 又不允许出现在表级触发器中,也是个问题现在只能向我一直相信的CSDN的各位大神们伸出援手了,看看具体是什么情况?
oracl
需求: 对库存表的增删改触发执行物资主表单价的更新;
条件: 1.根据先进先出,这个单价是最新进库的单价
2.这个单价还的是保证其数量不为0 的情况下;
create or replace trigger kcdanjia_trigger
after update or insert or delete on gmkucunxinxi
for each row
--库存先进先出更新物资主表单价DECLARE
danjias number(14,2);
begin
--提取先进的并且数量大于0的库存物资单价
select g.danjia into danjias
from gmkucunxinxi g
where g.kucunid = (select min(kucunid)
from gmkucunxinxi
where wuzimingcheng = :new.wuzimingcheng
and shuliang > 0); dbms_output.put_line(danjias);
dbms_output.put_line(:new.wuzimingcheng); --把单价更新到物资主表
update GMWUZIXINXI set danjia = danjias where WUZI_ID = :new.wuzimingcheng ;end;主要报错:gmkucunxinxi 表发生变化,触发器/函数不能读它;后期也根据网上说的:你这报错是因为变异表的问题,触发器尝试读取正在发生改变的表时都会报这个错误。以及:new,:old的用法问题 : insert是插入数据,所以只会有new,
delete是删除数据,所以只会有old,
update是更新数据,所以new和old都有就改成这种形式的:
DECLARE
danjias number(14,2);
ids number(10);
wuzimingchengs number(10);
begin
if inserting then
wuzimingchengs := :new.wuzimingcheng;
dbms_output.put_line(wuzimingchengs);
select kucunid into ids
from gmkucunxinxi
where wuzimingcheng = 318
and shuliang > 0 and rownum=1; dbms_output.put_line(ids);
end if;含有inserting,updating,delete判断的形式,结果也是一样;
现在我也尝试了变 行级触发器 为 语句级触发器,但关键我还必行的用到 库存表更新时的数据;
但是 new old 又不允许出现在表级触发器中,也是个问题现在只能向我一直相信的CSDN的各位大神们伸出援手了,看看具体是什么情况?
oracl
解决方案 »
- 求高手解决怎么实现数据库里面数据关联?DBA求进。
- !!在线急等高手!!多表连接,字段为空,结果集为空问题!
- agentctl start agent 出错
- sql 语句问题请教,一直没有搞出来,多谢了
- 一比较难的oracle的select写法
- Oracle数据库运行一段时间后就无法连接,提示Ora-12547:TNS丢失联系
- 如何写语句创建一个表让他的日期字段固定格式为(yyyy/mm/dd hh:mm:ss)!在线等!!
- oracle中,什么内在函数能把半角转成全角?急
- 小弟自己写的触发器,请问错在那里?
- 急急急!!!在线等候???
- SQL更新,字段不是更新而是在原来基础上追加
- Order by排序的问题
可关键我的提取这个触发表里的数据啊,怎么解决,望大神们帮忙
ORA-4091错误是在点火触发器时引发的而不是在创建该表时引发的!!!
要消除变化表的错误,不能用行级触发器中查询它,但可以在语句级触发器中查询它。
可关键是用语句级触发器就不能用new old了,可是我要用到这个更新的表记录中的数据的
还是没解决啊,大神快快现身吧
http://blog.csdn.net/ziwen00/article/details/8574127
测试就是新增一条库存记录:insert into gmkucunxinxi
(kucunid, cangku, shuliang, danjia, jine, linjiekucun, WUZIMINGCHENG)
values
(gmkucunxinxi_kucunid.nextval, '1', 13, 2, 26, '8', 318)
DROP TABLE WUZI;*/--创建表 库存表
CREATE TABLE KUCUN(
GOODSID NUMBER(10), --货物
PURCHASETIME DATE,--进货时间
PRICE NUMBER(20,4) --货物单价
);
/
--创建表 物资表 (被更新的主表)
CREATE TABLE WUZI(
GOODSID NUMBER(10), --货物
PRICE NUMBER(20,4) --货物单价
);
/--生成测试数据
BEGIN
FOR I IN 1..10 LOOP
INSERT INTO KUCUN VALUES(I,SYSDATE - NUMTODSINTERVAL(I,'HOUR'),I+I*0.1);
END LOOP;
COMMIT;
END;
/SELECT * FROM KUCUN;--生成测试数据
BEGIN
FOR I IN 1..10 LOOP
INSERT INTO WUZI VALUES(I,I);
END LOOP;
COMMIT WORK;
END;
/SELECT * FROM WUZI;--触发器,写入一条心的GOODSID为1的信息,然后更新主表,创建触发器
CREATE OR REPLACE TRIGGER TRI_KUCUN
--在插入之前
BEFORE INSERT OR UPDATE ON KUCUN
FOR EACH ROW
DECLARE
N_PRICE KUCUN.PRICE%TYPE;
BEGIN
--得到插入数据之前的最早的价格
--比如本次插入的是13,但是实际上查出来的是1-10的GOODSID日期最小的价格,而不是1-10包含13
BEGIN
SELECT DISTINCT FIRST_VALUE(T.PRICE) OVER(PARTITION BY T.GOODSID ORDER BY T.PURCHASETIME)
INTO N_PRICE
FROM KUCUN T
WHERE T.GOODSID = :NEW.GOODSID;
EXCEPTION
--处理NO_DATA_FOUND异常
--用于处理那种,先进先出,但是进去的已经被处理掉了的情况,即所有的库存表中的记录都已经被更新到物资表中
WHEN NO_DATA_FOUND THEN
N_PRICE:=:NEW.PRICE;
END;
--更新物资表的GOODSID的价格
UPDATE WUZI
SET WUZI.PRICE = N_PRICE
WHERE WUZI.GOODSID = :NEW.GOODSID;
--如果物资表的GOODSID不存在的话,则插入
IF SQL%ROWCOUNT <1 THEN
INSERT INTO WUZI(GOODSID,PRICE) VALUES(:NEW.GOODSID,N_PRICE);
END IF;
END;
/--测试数据
--插入GOODSID为1,PRICE为100,应该更新为1.1
INSERT INTO KUCUN VALUES(1,SYSDATE,100);
SELECT * FROM WUZI;
--插入GOODSID为13,PRICE为100,应该插入一条新的为100
INSERT INTO KUCUN VALUES(13,SYSDATE,100);
SELECT * FROM WUZI;
after表示触发器在插入、更新或者删除之后才会调用下面的语句块,但是当前的事务还没有被提交,所以为了保证数据的一致性,Oracle是不会让你操作一个变动了的表,因此提示你所遇见的错误。
就将after修改为before,这样在对库存表进行变动之前,就可以得到你想要的信息,然后缓存起来,使用:NEW.获取最新插入的数据与缓存的数据作比较,然后去更新物资表。
另外:在TRIGGER的语句块里面,可以使用类似于 IF INSERTING THEN V_ACTION := 'INSERT';
ELSIF UPDATING THEN V_ACTION := 'UPDATE';
ELSIF DELETING THEN V_ACTION := 'DELETE';
ELSE V_ACTION :='OTHER';
END IF;的语句来区分锁进行的操作,可以解决上面的OLD NEW的问题
就这一句话我之前的努力就这么完了,我就是一个苦命的娃啊现在问题又来了:这条sql的问题此条sql主要实现的功能:查物资库存表依照先进先出原则查询最先进库存的并且数量大于0的物资单价;
正常情况下
select g.danjia
from gmkucunxinxi g
where g.kucunid = (select min(kucunid)
from gmkucunxinxi
where wuzimingcheng = 203
and shuliang > 0); 这条sql就能解决问题;
可结合流程联动设置的限制问题,代码中这个wuzimingcheng = 203,已经随着浏览框默认加到sql的关联
条件上了,至于加到了最前面还是最后面还不清楚,先假设加载条件的最前面吧;
可是我的子查询里的 这条wuzimingcheng = 203怎么办了????经改后,成这样:select k.danjia from gmwuzixinxi g,gmkucunxinxi k
where g.wuzi_id=k.wuzimingcheng and k.shuliang > 0 and rownum = 1其实后面默认加上如:and k.WUZIMINGCHENG = 203,本思路是 这两个物资主表和库存表关联上了,库存数量也大于0了,默认是正序,选第一行,就能实现
先进来的 库存id最小的;可是却忽略了 这个默认是正序的也只是在 order by k.kucunid 后面什么不写的情况下,这时默认是正序的;
但加上order by ,假设这and k.WUZIMINGCHENG = 203,是加在前面的先不考虑但仍有个关键问题select k.kucunid,k.danjia
from gmwuzixinxi g, gmkucunxinxi k
where g.wuzi_id = k.wuzimingcheng
and k.WUZIMINGCHENG = 203
and k.shuliang > 0
and rownum = 1
order by k.kucunid这条sql显示的不是正序排列完取id最小的第一条,而是随机的,谁都有可能是第一条;
现在正在想办法解决,望大神,大哥们再帮我想想,折腾一天了,脑袋都冒烟了!!!
可以使用Oracle的分析函数来解决
大哥,基本学习了分析函数,功能很强大,但分析语句确实与我的联动设置不符合啊,这个联动设置已经默认为简单sql的形式,select * from a,b where a.id=b.aid and ...这种形式的,
悲剧,不过仍要谢谢大哥,希望大哥再出谋划策啊
没有填写按哪些字段排序的功能吗?
看看源码吧,你怎么知道到底是怎么order by的.
都是你的YY
现在已经落实无法解决,已经向上审批了,
在这特别感谢ziwen大哥,希望给小弟个机会交个朋友
方面的话可以把QQ发到我邮箱:[email protected]
以后有问题还的向大哥多多请教了,谢谢再次感谢!!!