在plpgsql语言的函数中,并具有:
"col" CHARACTER VARYING = 'a';
(可以'b'
)"rec" RECORD;
持有记录来自:(SELECT 1 AS "a", 2 AS "b")
"res" INTEGER;
"col"
我需要从中引用命名列"rec"
。所以如果"col"
有'b'
我会引用"rec"."b"
,然后将其值保存到"res"
.
在plpgsql语言的函数中,并具有:
"col" CHARACTER VARYING = 'a';
(可以'b'
)"rec" RECORD;
持有记录来自:(SELECT 1 AS "a", 2 AS "b")
"res" INTEGER;
"col"
我需要从中引用命名列"rec"
。所以如果"col"
有'b'
我会引用"rec"."b"
,然后将其值保存到"res"
.
您不能在 plpgsql 中按名称引用匿名记录类型的列。即使您在SELECT
语句中的示例中拼出列别名,这些也只是噪音并被丢弃。
如果要按名称引用记录类型的元素,则需要使用众所周知的类型。创建并使用一个类型:
CREATE TYPE my_composite_type(a int, b int);
或者使用与任何现有表关联的行类型。您可以将表名写为数据类型。
DECLARE
rec my_composite_type;
...
然后你需要一个条件语句或动态 SQL来使用作为标识符的值。"col"
条件语句:
IF col = 'a' THEN
res := rec.a;
ELSIF col = 'b' THEN
res := rec.b;
ELSE
RAISE EXCEPTION 'Unexpected value in variable "col": %', col;
END IF;
对于两种可能的情况,这就是要走的路。
或动态 SQL:
EXECUTE 'SELECT $1.' || col
INTO res
USING rec;
我在这里没有看到问题,但要小心使用动态 SQL 进行 SQL 注入。如果col
可以保存任意数据,则需要使用quote_ident()
or转义它format()
使用动态 SQL 演示更强大但也更复杂的变体。
创建(临时!)已知类型进行测试的快速而肮脏的方法:
CREATE TEMP TABLE rec_ab(a int, b int);
功能:
CREATE OR REPLACE FUNCTION f_test()
RETURNS integer AS
$func$
DECLARE
col text := 'a'; -- can be 'b'
rec rec_ab;
res int;
BEGIN
rec := '(1, 2)'::rec_ab;
EXECUTE 'SELECT $1.' || col
INTO res
USING rec;
RETURN res;
END
$func$
LANGUAGE plpgsql VOLATILE;
称呼:
SELECT f_test();
回报:
f_test
----
1