使用Postgres 8.4中每行调用一次的函数进行更新

时间:2011-12-30 08:12:53

标签: sql database postgresql sql-update

我有以下UPDATE语句:

update mytable
   set a = first_part(genid()),
       b = second_part(genid()),
       c = third_path(genid())
 where package_id = 10;

在这个例子中,每行调用函数genid()三次,这是错误的 - 我希望它只为mytable的每一行调用一次。

我正在使用PostgreSQL 8.4数据库。如何写出正确的更新?

我尝试过这样的事情:

update mytable
   set a = first_part(g),
       b = second_part(g),
       c = third_path(g)
 where package_id = 10
  from genid() as g;

但它不起作用,因为genid()仅为整个更新语句调用一次

3 个答案:

答案 0 :(得分:8)

您是否尝试过Postgres的非标准UPDATE .. FROM条款?我想,这会起作用

update mytable
   set a = first_part(gen.id),
       b = second_part(gen.id),
       c = third_path(gen.id)
  from (
          select genid() as genid, id
          from mytable 
          where package_id = 10
       ) gen
 where mytable.id = gen.id;
 --and package_id = 10 -- This predicate is no longer necessary as the subquery
                       -- already filters on package_id, as Erwin mentioned

请注意,我强制在子选择中的genid()中为每个记录强制调用mytable一次。然后,我使用假设的mytable列自我加入genid。 请参阅此处的文档:

http://www.postgresql.org/docs/current/interactive/sql-update.html

这似乎只是在Postgres 9.0中引入的。如果这看起来太复杂(即不太可读),你仍然可以使用pgplsql作为用户Florin suggested here。< / p>

答案 1 :(得分:0)

你能检查一下这是否适用于postgres?

update 
  (select 
     a, b, c, genid() as val
  from mytable
  where package_id = 10
  )
set a = first_part(val),
       b = second_part(val),
       c = third_path(val);

<强>更新 只为ideea:你能用光标试试吗?

DECLARE c1 CURSOR FOR 
      select 
         a, b, c, genid() as val
      from mytable
      where package_id = 10; 
...
UPDATE table SET ... WHERE CURRENT OF c1;

答案 2 :(得分:0)

我建议使用以下 -

DECLARE @genID VARCHAR(100) -- or appropriate datatype

SET @genID = genid() -- Or select @genID = genid()    
update mytable    
   set a = first_part(@genID),
       b = second_part(@genID),
       c = third_path(@genID)
where package_id = 10;