【问题标题】:Dynamically access column value in record动态访问记录中的列值
【发布时间】:2015-12-06 01:49:04
【问题描述】:

是否可以通过名称动态访问记录中的列值?

我正在编写一个执行动态 SQL 命令的触发器函数,我想按列名从 NEW 记录中动态提取列值。

这是我正在尝试做的一个简化示例:

$$
DECLARE
   command text := 'UPDATE $1 SET $2 = $3';
   myColumn := 'votes'
BEGIN
   EXECUTE command using 'anotherTable', myColumn, NEW.myColumn;
END
$$

【问题讨论】:

    标签: postgresql triggers plpgsql dynamic-sql procedures


    【解决方案1】:

    可能,但EXECUTEUSING 子句只能传递
    虽然 标识符 必须连接表名和列名(小心 SQL 注入!)在执行命令之前。使用format() (Postgres 9.1+) 可以这样工作:

    $$
    DECLARE
       _command text := 'UPDATE %I SET %I = $1 WHERE ....'; -- add WHERE condition
       _col text := 'votes';
    BEGIN
       EXECUTE format(_command, 'anotherTable', _col)
       USING  NEW.myColumn;
    END
    $$;
    

    修正了几个小问题。

    必须提到NEW只在触发函数中可用。

    请注意,'anotherTable' 在此处区分大小写(被转换并从 字符串 中转义),而 NEW.myColumn 则不(作为标识符处理)。在 Postgres 中使用合法的、小写的、不带引号的标识符,让您的生活更轻松。

    更多解释和链接的相关答案:


    通过列名从NEW 记录中动态提取列值。

    ...你可以使用hstore #= operator

    或者您也可以使其与动态 SQL 的标准功能一起使用:

    $$
    DECLARE
       _col text := 'votes';
       _new_col text := 'column_name_in_new';  -- enter column name here, case sensitive
    BEGIN
       EXECUTE format(
           'UPDATE %I SET %I = $1.%I WHERE ... '  -- add WHERE condition
         , 'anotherTable', _col, _new_col)
       USING  NEW;  -- pass whole row
    END
    $$;

    相关:

    【讨论】:

    • 感谢您的出色回答,但这仍然不是我想要做的。在您的示例中,您明确访问了NEW.myColumn; 我想根据预先存在的值动态访问列,例如NEW[_column]。有人建议在别处使用 hstore。这有效:hstore(NEW)->_column 动态访问 NEW 中的 votes 列。但是我对 hstore 一点也不熟悉,如果有更简单的选择,我宁愿不启用扩展。
    • @RedHusky:我为此添加了另一个解决方案。
    猜你喜欢
    • 1970-01-01
    • 2012-05-25
    • 2014-11-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-08-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多