我是sql / plpgsql的新手并尝试进行涉及条件的更新; plpgsql不允许按照我的想法使用临时变量,使用我创建的两个变量中的任何一个时都会出现错误。我被告知我不能使用最近更新的列来更新同一更新中的另一个列。
我创建了“tempc”,因为所谓的限制是在同一句子中更新“ivafactura”而“tipoi”作为布尔值来避免两次评估相同的条件。
如何正确使用“tempc”和“tipoi”或者如何重写函数以高效运行它?
提前致谢,
何塞
CREATE OR REPLACE FUNCTION updatecosto(v_centro smallint, v_desde date) RETURNS void AS
$BODY$
declare
tempc numeric;
tipoi boolean;
begin
update fletes
tipoi := (select ivafronterizo from destinos where destinos.destino=fletes.origen)=2 and
(select ivafronterizo from destinos where fletes.destino=destinos.destino)=2,
tempc := kilos * case
when tipoi
then (select costounitario2 from costosf where diaembarque>costosf.desde limit 1 desc)
else (select costounitario from costosf where diaembarque>costosf.desde limit 1 desc)
end,
set
costogas = tempc,
ivagas = tempc * case
when tipoi
then (select pivafro from iva where diaembarque>=desde order by desde desc limit 1 desc)
else (select pivanac from iva where diaembarque>=desde order by desde desc limit 1 desc)
end
where diaembarque>=v_desde
and diaembarque<=coalesce((select desde - 1 from costof where desde>v_desde and centroemabrcador=v_centro order by desde limit 1), current_date)
and origen=v_centro;
end;
$BODY$
LANGUAGE plpgsql VOLATILE
答案 0 :(得分:0)
关键是 - 你不能使用变量,直到你循环遍历行。变量可以包含标量值,并且您希望为每行计算tipoi
和tempc
。我认为在你的情况下你可以使用预先计算的列,就像这样。
CREATE OR REPLACE FUNCTION updatecosto(v_centro smallint, v_desde date) RETURNS void AS
$BODY$
declare
tempc numeric;
tipoi boolean;
begin
with cte1 as (
select
*
(select ivafronterizo from destinos where destinos.destino=fletes.origen)=2 and
(select ivafronterizo from destinos where fletes.destino=destinos.destino)=2 as tipoi,
from fletes
where diaembarque>=v_desde
and diaembarque<=coalesce((select desde - 1 from costof where desde>v_desde and centroemabrcador=v_centro order by desde limit 1), current_date)
and origen=v_centro;
), cte2 as (
select
*,
kilos * case
when tipoi
then (select costounitario2 from costosf where diaembarque>costosf.desde limit 1 desc)
else (select costounitario from costosf where diaembarque>costosf.desde limit 1 desc)
end as tempc
from cte1
)
update fletes as f
costogas = c.tempc,
ivagas = c.tempc * case
when tipoi
then (select pivafro from iva where diaembarque>=desde order by desde desc limit 1 desc)
else (select pivanac from iva where diaembarque>=desde order by desde desc limit 1 desc)
end
from cte2 as c
where c.id = f.id
end;
$BODY$
LANGUAGE plpgsql VOLATILE
我确信有一种方法可以进一步简化您的查询,只需要查看您的架构。另外我建议对表使用别名,如果不了解哪个列属于哪个表,很难读取复杂的查询。