嵌套选择中的动态sql选择

时间:2015-01-25 08:22:58

标签: sql arrays postgresql plpgsql dynamic-sql

我们假设我有一个表tasksprojectswork_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
    )

并收到正确的结果。

我的代码出了什么问题?

2 个答案:

答案 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表达式中。