我们假设我有一个表tasks
,projects
和work_items
,所有表都有一个包含自定义json对象的列fields
值。
现在假设我想编写一个函数来查询任意表的字段名称。
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($1)
) 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 json_object_keys(fields) AS fieldName
FROM tasks
)
并收到正确的结果。
我的代码出了什么问题?
答案 0 :(得分:1)
EXECUTE
语句不返回可用作子查询的关系。相反,如果它返回任何内容,它会通过INTO
子句填充变量或单行。后者显然不符合您的要求,因此您坚持使用第一个。更优雅的解决方案是向外移动EXECUTE
语句:
EXECUTE
'SELECT array_agg(DISTINCT fields) FROM ' ||
'(SELECT json_object_keys(fields) AS fields FROM ' || quote_ident($1) || ') AS x'
INTO fieldNames;
答案 1 :(得分:0)
最糟糕的问题是EXECUTE语句的错误位置。它是一个PLpgSQL语句,然后它不能放在任何SQL表达式中。