详细删除记录 table 后更新主 table 的过程出错
Error in procedure which updates master table after deleting records in detail table
在 Interbase 2009 数据库中,我有 master 和 detail tables(Tmaster, Tdetails)。
Tmaster:
master_id(pk)
DocSumma
DocSummaDol
T详情:
det_id
master_id(fk)
price1,price2
qnt
在我 delete/update 子 table(Tdetails) 过程中记录后必须更新主 table(Tmaster) 中的摘要。
我有两个问题:
- 如果过程包含此 if 子句:
if (m.DocSumma=0) then begin delete from Tmaster m where m.master_id=:master_id; end
它returns这个错误:
Column does not belong to referenced table. Dynamic SQL Error. SQL
error code = -206. Column unknown.
- 如果没有 if 子句,我会遇到第二个问题:程序工作 非常慢。 13 小时后结束:)
有时在 IBExpert 中我会收到此错误:
Arithmetic overflow or division by zero has occurred. arithmetic
exception, numeric overflow, or string truncation.
SQLCODE: -802 GDSCODE: 335544321
我的 Psql 代码有什么问题?
alter procedure sp_recalculate_summa
as
declare variable master_id integer;
declare variable det_id integer;
declare variable sum1 decimal(8,4) ;
declare variable sum2 decimal(8,4) ;
begin
for select m.master_id
from Tmaster m
into :master_id
do begin
sum1=0;
sum2=0;
for select det_id,
sum(d.price1*d.qnt)as summa1,
sum(d.price2*d.qnt)as summa2
from Tdetails d, Tmaster m
where d.det_id=:master_id
group by det_id
into :det_id,:sum1,:sum2
do
if (m.DocSumma=0) then begin
delete from Tmaster m where m.master_id=:master_id;
end
Else begin
update Tmaster set DocSumma=:sum1 where master_id=:master_id;
update Tmaster set DocSummaDol=:sum2 where master_id=:master_id;
end
end
end
问题不在于 delete 语句,而在于 if (m.DocSumma=0) then begin
。您不能像在 PSQL 块中那样引用 table。您需要将该列值显式分配给局部变量。
例如:
alter procedure sp_recalculate_summa
as
declare variable master_id integer;
declare variable DocSumma decimal(8,4);
declare variable det_id integer;
declare variable sum1 decimal(8,4) ;
declare variable sum2 decimal(8,4) ;
begin
for select m.master_id, m.DocSumma
from Tmaster m
into master_id, DocSumma
do begin
sum1=0;
sum2=0;
for select det_id,
sum(d.price1*d.qnt)as summa1,
sum(d.price2*d.qnt)as summa2
from Tdetails d, Tmaster m
where d.det_id=:master_id
group by det_id
into det_id,sum1,sum2
do
if (DocSumma=0) then begin
-- etc..
end
end
end
补充说明:
我质疑条件 if (m.DocSumma=0) then begin
的正确性(if (DocSumma=0) then begin
在我提议的更改中),这不应该是 if (sum1 = 0) then begin
吗?就像,它应该使用更新的总和,而不是旧的总和。
还有,为什么要更新TMASTER
两次?使用单个更新会更有效:
update Tmaster set DocSumma=:sum1, DocSummaDol=:sum2 where master_id=:master_id;
其中一些更改最好通过 TDETAILS
和 TMASTER
上的触发器来完成,而不是使用延迟的显式重新计算。
在 Interbase 2009 数据库中,我有 master 和 detail tables(Tmaster, Tdetails)。
Tmaster:
master_id(pk) | DocSumma | DocSummaDol |
---|
T详情:
det_id | master_id(fk) | price1,price2 | qnt |
---|
在我 delete/update 子 table(Tdetails) 过程中记录后必须更新主 table(Tmaster) 中的摘要。
我有两个问题:
- 如果过程包含此 if 子句:
if (m.DocSumma=0) then begin delete from Tmaster m where m.master_id=:master_id; end
它returns这个错误:
Column does not belong to referenced table. Dynamic SQL Error. SQL error code = -206. Column unknown.
- 如果没有 if 子句,我会遇到第二个问题:程序工作 非常慢。 13 小时后结束:)
有时在 IBExpert 中我会收到此错误:
Arithmetic overflow or division by zero has occurred. arithmetic exception, numeric overflow, or string truncation. SQLCODE: -802 GDSCODE: 335544321
我的 Psql 代码有什么问题?
alter procedure sp_recalculate_summa
as
declare variable master_id integer;
declare variable det_id integer;
declare variable sum1 decimal(8,4) ;
declare variable sum2 decimal(8,4) ;
begin
for select m.master_id
from Tmaster m
into :master_id
do begin
sum1=0;
sum2=0;
for select det_id,
sum(d.price1*d.qnt)as summa1,
sum(d.price2*d.qnt)as summa2
from Tdetails d, Tmaster m
where d.det_id=:master_id
group by det_id
into :det_id,:sum1,:sum2
do
if (m.DocSumma=0) then begin
delete from Tmaster m where m.master_id=:master_id;
end
Else begin
update Tmaster set DocSumma=:sum1 where master_id=:master_id;
update Tmaster set DocSummaDol=:sum2 where master_id=:master_id;
end
end
end
问题不在于 delete 语句,而在于 if (m.DocSumma=0) then begin
。您不能像在 PSQL 块中那样引用 table。您需要将该列值显式分配给局部变量。
例如:
alter procedure sp_recalculate_summa
as
declare variable master_id integer;
declare variable DocSumma decimal(8,4);
declare variable det_id integer;
declare variable sum1 decimal(8,4) ;
declare variable sum2 decimal(8,4) ;
begin
for select m.master_id, m.DocSumma
from Tmaster m
into master_id, DocSumma
do begin
sum1=0;
sum2=0;
for select det_id,
sum(d.price1*d.qnt)as summa1,
sum(d.price2*d.qnt)as summa2
from Tdetails d, Tmaster m
where d.det_id=:master_id
group by det_id
into det_id,sum1,sum2
do
if (DocSumma=0) then begin
-- etc..
end
end
end
补充说明:
我质疑条件
if (m.DocSumma=0) then begin
的正确性(if (DocSumma=0) then begin
在我提议的更改中),这不应该是if (sum1 = 0) then begin
吗?就像,它应该使用更新的总和,而不是旧的总和。还有,为什么要更新
TMASTER
两次?使用单个更新会更有效:update Tmaster set DocSumma=:sum1, DocSummaDol=:sum2 where master_id=:master_id;
其中一些更改最好通过
TDETAILS
和TMASTER
上的触发器来完成,而不是使用延迟的显式重新计算。