动态访问记录中的列值

Dynamically access column value in record

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

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

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

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

那是可能,但是EXECUTEUSING子句只能传.
identifiers like table 和列名必须连接(警惕 SQL 注入!) 执行命令之前。使用 format() (Postgres 9.1+) 它可以像这样工作:

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

修正了传递过程中的几个小问题。

必须指出的是NEW仅在触发器函数中可用。

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

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

  • PL/pgSQL: General Way to Update N Columns in Trigger?
  • INSERT with dynamic table name in trigger function
  • Table name as a PostgreSQL function parameter
  • Are PostgreSQL column names case-sensitive?

To dynamically extract a column value from a NEW record by column name.

...您可以使用 hstore #= operator:

  • How to set value of composite variable field using dynamic SQL

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

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

相关:

  • Creating a trigger for child table insertion returns confusing error