如何在条件postgresql更新中使用临时变量?

时间:2013-08-26 03:31:17

标签: postgresql conditional plpgsql

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

1 个答案:

答案 0 :(得分:0)

关键是 - 你不能使用变量,直到你循环遍历行。变量可以包含标量值,并且您希望为每行计算tipoitempc 。我认为在你的情况下你可以使用预先计算的列,就像这样。

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 

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