动态 sql select 嵌套 select 中的离子
dynamic sql selection in nested select
假设我有一个 tables tasks
、projects
和 work_items
,它们都有一个包含 fields
的列 json 自定义值的对象。
现在假设我想编写一个函数来查询任意 table 的字段名称。
CREATE OR REPLACE FUNCTION getFieldNames(varchar) RETURNS varchar[] AS
$BODY$
DECLARE
fieldNames varchar[];
BEGIN
fieldNames := ARRAY(SELECT DISTINCT fieldName FROM
(EXECUTE 'SELECT json_object_keys(fields) AS fieldName FROM '
|| quote_ident()
) AS derivedFields
);
RETURN fieldNames;
END
$BODY$
LANGUAGE 'plpgsql';
但是错误的是:
ERROR: syntax error at or near "'SELECT json_object_keys(fields) AS fieldName FROM'"
LINE 8: (EXECUTE 'SELECT json_object_keys(fields) AS fieldNa..
嵌套 select 本身是合理的,因为我通过将执行替换为
进行了验证
(SELECT json_object_keys(fields) AS fieldName
FROM tasks
)
并收到正确的结果。
我的代码有什么问题?
EXECUTE
语句不是 return 可以用作子查询的关系。相反,如果 return 有任何内容,它会通过 INTO
子句填充一个变量或一行。后者显然不符合您的要求,因此您只能选择第一个。更优雅的解决方案是将 EXECUTE
语句向外移动:
EXECUTE
'SELECT array_agg(DISTINCT fields) FROM ' ||
'(SELECT json_object_keys(fields) AS fields FROM ' || quote_ident() || ') AS x'
INTO fieldNames;
最严重的问题是EXECUTE语句的位置错误。它是一个 PLpgSQL 语句,因此它不能放在任何 SQL 表达式中。
假设我有一个 tables tasks
、projects
和 work_items
,它们都有一个包含 fields
的列 json 自定义值的对象。
现在假设我想编写一个函数来查询任意 table 的字段名称。
CREATE OR REPLACE FUNCTION getFieldNames(varchar) RETURNS varchar[] AS
$BODY$
DECLARE
fieldNames varchar[];
BEGIN
fieldNames := ARRAY(SELECT DISTINCT fieldName FROM
(EXECUTE 'SELECT json_object_keys(fields) AS fieldName FROM '
|| quote_ident()
) AS derivedFields
);
RETURN fieldNames;
END
$BODY$
LANGUAGE 'plpgsql';
但是错误的是:
ERROR: syntax error at or near "'SELECT json_object_keys(fields) AS fieldName FROM'"
LINE 8: (EXECUTE 'SELECT json_object_keys(fields) AS fieldNa..
嵌套 select 本身是合理的,因为我通过将执行替换为
进行了验证 (SELECT json_object_keys(fields) AS fieldName
FROM tasks
)
并收到正确的结果。
我的代码有什么问题?
EXECUTE
语句不是 return 可以用作子查询的关系。相反,如果 return 有任何内容,它会通过 INTO
子句填充一个变量或一行。后者显然不符合您的要求,因此您只能选择第一个。更优雅的解决方案是将 EXECUTE
语句向外移动:
EXECUTE
'SELECT array_agg(DISTINCT fields) FROM ' ||
'(SELECT json_object_keys(fields) AS fields FROM ' || quote_ident() || ') AS x'
INTO fieldNames;
最严重的问题是EXECUTE语句的位置错误。它是一个 PLpgSQL 语句,因此它不能放在任何 SQL 表达式中。