Sql 在Postgres 8.4中,每行调用一次函数进行更新
我有以下更新声明:Sql 在Postgres 8.4中,每行调用一次函数进行更新,sql,database,postgresql,sql-update,Sql,Database,Postgresql,Sql 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 myta
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;
但是它不起作用,因为整个update语句只调用了
genid()
一次。您尝试过Postgres的非标准更新吗。。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
请注意,我正在强制子选择中的mytable
中的每个记录只调用一次genid()
。然后我使用一个假设的id
列自连接mytable
和gen
。
请参阅此处的文档:
不过,这似乎只是在Postgres 9.0中引入的。如果这看起来太复杂(即不太可读),您仍然可以使用pgplsql作为用户。您能检查一下这在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);
更新:
你能用光标试试吗
DECLARE c1 CURSOR FOR
select
a, b, c, genid() as val
from mytable
where package_id = 10;
...
UPDATE table SET ... WHERE CURRENT OF c1;
我建议使用以下方法-
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;
你不能把它放在一个存储过程中,然后首先调用
genid()
,将它存储在一个变量中,然后在你的update语句中使用它吗?你太简化了这个例子,我怀疑你有gen_id(column)@Florin No,genid不带参数,它在每次调用时根据任意序列和随机生成器生成一个唯一的值。这就是为什么我希望对mytable的每一行调用它一次。看起来答案中已经有了一个有效的解决方案,但是为完整的genid
+定义一个行级触发器(在插入/更新该列时更新a、b和c)是一个选项吗?附加列不是一个选项,我们有大约2000个这样的表,模式是相当稳定的。此列对于数百万条记录来说开销太大。与我冗长的解决方案相比,这可能是阻力最小的路径。。。(如果在这种情况下允许使用pgplsql)在这种情况下,整个表更新只调用一次genid()
,对吗?我需要为每一行调用一次。是的,整个表更新只调用一次。在您的情况下,我认为用户Lukas建议了实现这一点的最合适的方法。这对PostgreSQL不起作用(您不能声明这样的变量),这非常有效,谢谢。不过,我有一些性能问题,因为这涉及到散列连接。第二个是多余的,其中package_id=10
。子查询已经进行了筛选(应该如此)。如果mytable.id
被编入索引(它应该是这样的),冗余检查就没有用了。@Cezariusz:您分析过执行计划了吗?如果您在主键上进行自联接,则联接应该相当有效。@ErwinBrandstetter:您是对的。我没有那样想过。现在我来修正+1,我喜欢你的答案。:)您可能应该链接到8.4版(OP的版本)或当前版本的手册。最好是/interactive
分支。不适用于任何版本的PostgreSQL,也称为“错误答案”。