CREATE OR REPLACE TRIGGER TRG_INVOICE
AFTER INSERT
ON INVOICE
FOR EACH ROW
DECLARE
V_SERVICE_COST FLOAT;
V_SPARE_PART_COST FLOAT;
V_TOTAL_COST FLOAT;
V_INVOICE_DATE DATE;
V_DUEDATE DATE;
V_REQ_ID INVOICE.SERVICE_REQ_ID%TYPE;
V_INV_ID INVOICE.INVOICE_ID%TYPE;
BEGIN
V_REQ_ID := :NEW.SERVICE_REQ_ID;
V_INV_ID := :NEW.INVOICE_ID;
SELECT SUM(S.SERVICE_COST) INTO V_SERVICE_COST
FROM INVOICE I, SERVICE_REQUEST SR, SERVICE S, SERVICE_REQUEST_TYPE SRT
WHERE I.SERVICE_REQ_ID = SR.SERVICE_REQ_ID
AND SR.SERVICE_REQ_ID = SRT.SERVICE_REQ_ID
AND SRT.SERVICE_ID = S.SERVICE_ID
AND I.SERVICE_REQ_ID = V_REQ_ID;
SELECT SUM(SP.PRICE) INTO V_SPARE_PART_COST
FROM INVOICE I, SERVICE_REQUEST SR, SERVICE S, SERVICE_REQUEST_TYPE SRT,
SPARE_PART_SERVICE SRP,
SPARE_PART SP
WHERE I.SERVICE_REQ_ID = SR.SERVICE_REQ_ID
AND SR.SERVICE_REQ_ID = SRT.SERVICE_REQ_ID
AND SRT.SERVICE_ID = S.SERVICE_ID
AND S.SERVICE_ID = SRP.SERVICE_ID
AND SRP.SPARE_PART_ID = SP.SPARE_PART_ID
AND I.SERVICE_REQ_ID = V_REQ_ID;
V_TOTAL_COST := V_SERVICE_COST + V_SPARE_PART_COST;
SELECT SYSDATE INTO V_INVOICE_DATE FROM DUAL;
SELECT ADD_MONTHS(SYSDATE, 1) INTO V_DUEDATE FROM DUAL;
UPDATE INVOICE
SET COST_SERVICE_REQ = V_SERVICE_COST, COST_SPARE_PART =
V_SPARE_PART_COST,
TOTAL_BALANCE = V_TOTAL_COST, PAYMENT_DUEDATE = V_DUEDATE, INVOICE_DATE =
V_INVOICE_DATE
WHERE INVOICE_ID = V_INV_ID;
END;
我尝试在用户插入行后计算一些列。 使用service_request_id我想计算服务/部件/总成本。另外,我想生成创建和截止日期。但是,我一直在
INVOICE正在变异,触发/功能可能看不到它
在插入语句后不确定表是如何变异的。
答案 0 :(得分:1)
在插入语句后不确定表是如何变异的。
想象一个简单的表格:
create table x(
x int,
my_sum int
);
和一个AFTER INSERT FOR EACH ROW触发器,与您的类似,它计算表中所有值的总和并更新my_sum
列。
现在想象一下这个插入语句:
insert into x( x )
select 1 as x from dual
connect by level <= 1000;
此单个语句基本上会插入1000条记录,每条记录的值为1
,请参阅此演示:http://sqlfiddle.com/#!4/0f211/7
因为在SQL中,每个单独的语句必须是ATOMIC(更多信息在这里:Statement-Level Read Consistency,只要最终结果正确(一致),Oracle就可以以任何方式自由执行此查询。它可以保存记录按执行顺序,可能按相反的顺序,它可以将批处理分成10个线程并并行执行。
由于触发器在插入每一行后单独触发,并且它无法事先知道“最终”结果,因此考虑到上述所有以下结果都是可能的,这取决于Oracle选择执行此查询的“内部”方法。如您所见,这些结果不符合一致性的定义。并且Oracle防止发出变异表错误。
换句话说 - 你的假设是坏的,你的设计有缺陷,你需要改变它。
| X | MY_SUM |
|---|--------|
| 1 | 1 |
| 1 | 2 |
| 1 | 3 |
| 1 | 4 |
...
...
或者也许:
| X | MY_SUM |
|---|--------|
| 1 | 1000 |
| 1 | 1000 |
| 1 | 1000 |
| 1 | 1000 |
| 1 | 1000 |
| 1 | 1000 |
| 1 | 1000 |
...
或者也许:
| X | MY_SUM |
|---|--------|
| 1 | 4 |
| 1 | 8 |
| 1 | 12 |
| 1 | 16 |
| 1 | 20 |
| 1 | 24 |
| 1 | 28 |
...
...