我有以下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()
仅为整个更新语句调用一次。
答案 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
列自我加入gen
和id
。
请参阅此处的文档:
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;