如何在plpgsql中的"EXECUTE format()"中使用变量

9

我想更新表格stats中的一列,该列需作为参数传入,然后返回该列的更新值[只有1行]:

CREATE FUNCTION grow(col varchar) RETURNS integer AS $$
DECLARE
tmp int;
BEGIN
    tmp := (EXECUTE format(
            'UPDATE stats SET %I = %I + 1
            RETURNING %I',
            col, col, col
            )
    );
    RETURN tmp;
END;

作为一个整体,我甚至不确定这是否是我想要的最佳方法,任何建议都将不胜感激!

你不能使用EXECUTE IMMEDIATE吗?请查看33.5.3节。 - cha
2
我只是好奇你的整体设计...根据你问题中的线索,这是一个保存统计数据的表格,存储过程旨在“增加”传入的特定统计数据?你决定使用列而不是查找表(即仅两列:stat_name、stat_value)有什么原因吗?那比使用列更灵活和常规...而且,那样就不需要动态SQL了。 - Ruslan
1
@cha:在plpgsql中没有EXECUTE IMMEDIATE。你链接的是ECPG(C语言嵌入式SQL)的一部分! - Erwin Brandstetter
1个回答

12

可以做到这一点。使用EXECUTE语句的INTO关键字,详见文档

CREATE OR REPLACE FUNCTION grow(_col text, OUT tmp integer)
   LANGUAGE plpgsql AS
$func$
BEGIN

EXECUTE format(
 'UPDATE stats
  SET    %1$I = %1$I + 1
  RETURNING %1$I'
 , _col)
INTO tmp;

END
$func$;

电话:

SELECT grow('counter');

使用OUT参数可以简化整体。
format()语法在手册中有解释

你可以直接运行UPDATE而不是调用函数:

UPDATE stats SET counter = counter + 1 RETURNING counter;

动态SQL函数很少有情况是不必要的复杂化。

替代设计

如果可能的话,请考虑不同的表格布局:按行而非列(如Ruslan建议的)。可以允许任意数量的计数器:

CREATE TABLE stats (
  tag text PRIMARY KEY
, counter int NOT NULL DEFAULT 0
);

电话:

UPDATE stats
SET    counter = counter + 1
WHERE  tag = 'counter1'
RETURNING counter;

或者考虑使用专用的SEQUENCE来计数...


谢谢!我之前不知道你用的一些东西。我试着查找了一下,但没有什么收获。但是,有一个表达式“%1$I”让我很困惑。请问有什么地方可以了解更多关于它的信息吗?再次感谢! - House3272
@House3272:中间的1$是指向提供的第一个参数的引用。我添加了一个链接,详细介绍了format()函数。 - Erwin Brandstetter

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接