如何在PostgreSQL中执行动态查询?

时间:2017-03-03 01:53:37

标签: postgresql dynamic-sql postgresql-9.3

我正在尝试执行以下动态sql,但我无法弄清楚如何执行此操作:

DROP FUNCTION f_mycross(text, text);

EXECUTE ('CREATE OR REPLACE FUNCTION f_mycross(text, text)
   RETURNS TABLE ("registration_id" integer, '
   || (SELECT string_agg(DISTINCT pivot_headers, ',' order by pivot_headers)
       FROM (SELECT DISTINCT '"' || qid::text || '" text' AS pivot_headers
             FROM answers) x)
   || ') AS ''$libdir/tablefunc'',''crosstab_hash'' LANGUAGE C STABLE STRICT;')

我对PostgreSQL比较陌生。

1 个答案:

答案 0 :(得分:1)

Like a_horse commentedEXECUTE不是SQL命令。它是PL / pgSQL命令,只能在函数体或DO语句中使用此过程语言。像:

DROP FUNCTION IF EXISTS f_mycross(text, text);

DO
$do$
BEGIN

EXECUTE (
   SELECT 'CREATE OR REPLACE FUNCTION f_mycross(text, text)
             RETURNS TABLE (registration_id integer, '
       || string_agg(pivot_header || ' text', ', ')
       || $$) AS '$libdir/tablefunc', 'crosstab_hash' LANGUAGE C STABLE STRICT$$
   FROM  (SELECT DISTINCT quote_ident(qid::text) AS pivot_header FROM answers ORDER BY 1) x
   );

END
$do$;  -- LANGUAGE plpgsql is the default

我添加了一些改进并简化了嵌套的SELECT查询。

重点

  • IF EXISTS添加到DROP FUNCTION,除非您确定该功能存在,或者您想要引发异常(如果不存在)。

  • 子查询中的
  • DISTINCT就足够了,外部SELECT中不需要另一个DISTINCT

  • 使用quote_ident()在必要时自动双重引用标识符。

  • 我们向EXECUTE提供的字符串周围不需要括号。

  • 使用$ -quotes进行更简单的嵌套引用。

  • 我们可以在子查询中应用ORDER BY,这通常比在外部聚合函数中添加ORDER BY快得多。