2017-02-15 39 views
2

我通过几场试图循环和运行它们的函数在给定列表循环:通过值的PL/pgSQL的

FOR field IN ARRAY['f1','f2'] LOOP 
    execute pg_temp.converFieldToLower(newTableNameRaw,field) 
END LOOP; 

这是我想要使用的功能:

CREATE OR REPLACE FUNCTION pg_temp.converFieldToLower(t varchar, f varchar) RETURNS void AS $$ 
#variable_conflict use_variable 
BEGIN 
    EXECUTE concat_ws (' ', 'UPDATE',t,'SET',f,'= LOWER(',f,')'); 
END; 
$$ LANGUAGE plpgsql; 

它看起来不是正确的方式来声明一个数组,我做错了什么?

ERROR: syntax error at or near "ARRAY" 
LINE 49:   FOR field IN ARRAY['f1','f2'] LOOP 
+0

你写*“fields”*,但是展示*常数值*。那么:常量,plpgsql参数或变量或表的字段?输入是一个实际的数组?你想放弃任何结果如展示或分配结果的目标?最好的解决方案取决于你的情况的细节。最好提供一个完整的(尽可能简单的)plpgsql函数,显示涉及的数据类型,函数参数等。 –

+0

我使用常量文本值作为示范。 –

回答

4

FOREACH loop的是专门为通过阵列值的元素迭代设计,例如:

FOREACH field IN ARRAY ARRAY['f1','f2'] LOOP 
    execute pg_temp.converFieldToLower(newTableNameRaw,field) into res; 
END LOOP; 

特征在Postgres的9.1中引入的。

0

你想unnest阵列。

FOR field IN unnest(ARRAY['f1','f2']) LOOP 
    execute pg_temp.converFieldToLower(newTableNameRaw,field) 
END LOOP; 
+0

这不应该工作 - 需要'FOR r IN SELECT unnest'。它应该比'FOREACH'慢得多# –

+0

'EXECUTE'不应该在这里使用 - 请参阅@Erwin的回复 –

2

首先,EXECUTE用于动态SQL,这里没有任何动态的。
您可能打算使用PERFORM来放弃结果。

FOREACH用于循环,如@klin already provided。更多细节:

或者你也可以使用纯SQL来代替,往往更简单更快:

PERFORM pg_temp.converFieldToLower(newTableNameRaw, t.val) 
FROM (VALUES ('f1'), ('f2')) t(val); -- for some given constants or variables 

最好的解决方案取决于形势的细节。 FOREACH可能是处理实际数组的一个好主意。

对于只有两个或三个常量或变量,我会拼出来,并避免任何开销。更简单,更快。

PERFORM pg_temp.converFieldToLower(newTableNameRaw, 'f1'); 
PERFORM pg_temp.converFieldToLower(newTableNameRaw, 'f2');