plpgsql 函数中对记录列的动态访问

Chr*_*isR 5 postgresql dynamic-sql plpgsql composite-types

如何动态地从 plpgsql 函数中的记录中寻址一列?

在以下代码段中,我可以访问一个变量entity.colname,该变量包含应在 IF 控制结构中检查的列。我正在研究如何foobarentity.colname. 这在 plpgsql 中可能吗?

IF NEW.foobar IS NULL THEN
    RAISE EXCEPTION '% cannot be null', foobar;
END IF;
Run Code Online (Sandbox Code Playgroud)

这是可以但行不通的事情。

IF NEW.entity.colname IS NULL THEN
    RAISE EXCEPTION '% cannot be null', entity.colname;
END IF;
Run Code Online (Sandbox Code Playgroud)

上面的例子只是为了说明我想要实现的目标,不要判断功能。:)

我正在使用 PostgreSQL 9.1。

Erw*_*ter 7

这很棘手,因为标识符不能是普通 SQL 中的变量。您需要使用动态 SQL withEXECUTE - 这仍然很棘手,因为变量在EXECUTE.

这是一个演示如何解决这个问题:

CREATE TYPE mytype AS (id int, txt text);

DO
$body$
DECLARE
    _val    mytype  := (1, NULL)::mytype;
    _name   text    := 'txt';
    _isnull boolean;
BEGIN
    EXECUTE 'SELECT $1.' || quote_ident(_name) || ' IS NULL'
    USING _val
    INTO _isnull;

    IF _isnull THEN
        RAISE NOTICE 'Column "%" cannot be null', _name;
    END IF;
END;
$body$
Run Code Online (Sandbox Code Playgroud)

在评论中使用@Jack 的想法进行了改进。

您不能使用内置的 plpgsql,FOUND因为它不是由EXECUTE(除了RETURN QUERY EXECUTE- more here)设置的。这就是我GET DIAGNOSTICS ...最初使用的原因。但最终用@Jack 的想法进行了简化。

quote_ident()确保名称在语法上有效并防止SQLi