在 plpgsql 中以编程方式访问记录的列

Posted

技术标签:

【中文标题】在 plpgsql 中以编程方式访问记录的列【英文标题】:Accessing columns of a record programatically in plpgsql 【发布时间】:2015-01-23 21:51:42 【问题描述】:

我正在尝试记录更改(如果对表进行了任何更改),但是在尝试循环访问列名时我被卡住了。我收到“数组值必须以“”开头...第 6 行 FOR over SELECT 行”错误。我不明白为什么会发生这种情况。该函数编译正常,但运行更新会出现该错误。

CREATE TABLE test(x varchar(50))

CREATE OR REPLACE FUNCTION testF()
RETURNS trigger
AS $$
DECLARE 
 col varchar[255]; //don't know if this is the right variable type to use
BEGIN
  IF OLD.* IS DISTINCT FROM NEW.* THEN
    FOR col in SELECT column_name FROM information_schema.columns WHERE table_schema = TG_TABLE_SCHEMA AND table_name = TG_TABLE_NAME LOOP
      INSERT INTO test(x) VALUES(col||'oldValue:'||OLD.col||'newValue:'||NEW.col); //I want to put the name and the old and new values in a varchar field
    END LOOP;
END IF;
RETURN NULL;
END $$ LANGUAGE plpgsql;

CREATE TRIGGER testT AFTER UPDATE
ON "triggerTable" FOR EACH ROW EXECUTE PROCEDURE testF();

【问题讨论】:

为什么不使用现有的解决方案之一? okbob.blogspot.co.uk/2015/01/… 或 wiki.postgresql.org/wiki/Audit_trigger_91plus @a_horse_with_no_name 会尝试 re:第一个评论正确的类型是postgres内置的name,AIUI是一种varchar[64],第二个评论,一点都不简单。 【参考方案1】:

要按名称获取 OLD 或 NEW 列,您必须使用 exec 一堆类型转换。

类似这样的:

execute '('||quote_literal(NEW::text)||'::'||quote_ident(pg_typeof(NEW))||
  ').'||quote_ident(col)||'::text';

这可能会导致某些浮点数的值不精确

【讨论】:

以上是关于在 plpgsql 中以编程方式访问记录的列的主要内容,如果未能解决你的问题,请参考以下文章

如何在plpgsql中读写psql变量

如何在不创建函数的情况下运行 plpgsql?

如何在android中以编程方式启用位置访问?

在 Ruby 中以编程方式访问属性/方法注释

在iOS中以编程方式拨打带有访问代码的电话号码

如果附件本身是邮件,如何在 Outlook 中以编程方式访问附件数据