在 plpgsql 语言的函数中,并且具有:
"col" CHARACTER VARYING = 'a';
(可'b'
)"rec" RECORD;
保存来自:(SELECT 1 AS "a", 2 AS "b")
"res" INTEGER;
我需要从"col"
引用"rec"
中的指定列。因此,如果"col"
有'b'
,我会引用"rec"."b"
,然后将其值保存到"res"
。
答案 0 :(得分:3)
您无法在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