我对 postgresql 还很陌生,并且在使用 for 循环更新表中的空值列时遇到问题。我正在处理的表格很大,因此为了简洁起见,我将给出一个较小的示例来说明要点。采取下表
+----+----------+----------+
| id | A | B | C |
+----+----------+----------+
| a | 1 | 0 | NULL |
| b | 1 | 1 | NULL |
| c | 2 | 4 | NULL |
| a | 3 | 2 | NULL |
| c | 2 | 3 | NULL |
| d | 4 | 2 | NULL |
+----+----------+----------+
我想编写一个 for 循环,它迭代所有行并执行一些操作
计算 a 列和 b 列中的值,然后在 c 中插入一个新值。
例如,其中 id = a ,更新表集 C = A*B ,或其中 id = d 设置 C = A + B 等。然后这会给我一个像这样的表
+----+----------+----------+
| id | A | B | C |
+----+----------+----------+
| a | 1 | 0 | 0 |
| b | 1 | 1 | NULL |
| c | 2 | 4 | NULL |
| a | 3 | 2 | 6 |
| c | 2 | 3 | NULL |
| d | 4 | 2 | 6 |
+----+----------+----------+
所以最终我想循环遍历表的所有行并根据“id”列中的值更新列 C。我编写的函数(没有给出任何错误,但也没有更新任何内容)看起来像这样......
-- DROP FUNCTION some_function();
CREATE OR REPLACE FUNCTION some_function()
RETURNS void AS
$BODY$
DECLARE
--r integer; not too sure if this needs to be declared or not
result int;
BEGIN
FOR r IN select * from 'table_name'
LOOP
select(
case
when id = 'a' THEN B*C
when id = 'd' THEN B+C
end)
into result;
update table set C = result
WHERE id = '';
END LOOP;
RETURN;
END
$BODY$
LANGUAGE plpgsql
我确信我错过了一些愚蠢的东西,可能是我正在返回的东西......在这种情况下无效。但由于我只想更新现有行,我是否需要返回任何内容?可能有比使用循环更简单的方法来做到这一点,但我想使用这种方法让它工作。
如果有人能指出我正确的方向或指出任何明显明显的我做错的事情,我将非常感激。
提前致谢。
不需要循环或函数,这可以通过单个来完成update
陈述:
update table_name
set c = case
when id = 'a' then a*b
when id = 'd' then a+b
else c -- don't change anything
end;
SQLFiddle:http://sqlfiddle.com/#!15/b65cb/2
您的函数没有执行任何操作的原因是:
update table set C = result
WHERE id = '';
您的列中没有包含空字符串的行id
。您的函数似乎也使用了错误的公式:when id = 'a' THEN B*C
我想应该是:then a*b
. As C
is NULL
最初,b*c
也将产生 null。所以即使if您在循环中的更新会找到一行,它将更新为NULL
.
您还从游标中错误地检索值。
如果你真的真的想在循环中低效地完成它,你的函数应该看起来像这样(未测试!):
CREATE OR REPLACE FUNCTION some_function()
RETURNS void AS
$BODY$
DECLARE
result int;
BEGIN
-- r is a structure that contains an element for each column in the select list
FOR r IN select * from table_name
LOOP
if r.id = 'a' then
result := r.a * r.b;
end if;
if r.id = 'b' then
result := r.a + r.b;
end if;
update table
set C = result
WHERE id = r.id; -- note the where condition that uses the value from the record variable
END LOOP;
END
$BODY$
LANGUAGE plpgsql
但再说一遍:如果你的表如你所说“巨大”,那么循环是一个非常糟糕的解决方案。关系数据库是用来处理数据“集”的。逐行处理是一种反模式,几乎总是会产生糟糕的性能。
或者反过来说:进行基于集合的操作(就像我的单update
示例)始终是更好的选择。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)