1

我是 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  
4

1 回答 1

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 

我确信有一种方法可以进一步简化您的查询,只需要查看您的架构。另外我建议对表使用别名,如果不了解哪个表属于哪个表,就很难阅读复杂的查询。

于 2013-08-26T04:40:06.453 回答