动态 sql select 嵌套 select 中的离子

dynamic sql selection in nested select

假设我有一个 tables tasksprojectswork_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 表达式中。