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

a64a0gku  于 2023-11-18  发布在  PostgreSQL
关注(0)|答案(1)|浏览(162)

我正在尝试执行以下动态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比较陌生。

fxnxkyjh

fxnxkyjh1#

EXECUTE不是SQL命令。它是PL/pgSQL命令,只能在该过程语言的代码块中使用。例如:

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', ', ')
       || $c$) AS '$libdir/tablefunc', 'crosstab_hash' LANGUAGE C STABLE STRICT$c$
   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()在必要的地方自动双引号标识符。否则,您可能会遇到语法错误和SQL注入。
  • 我们提供给EXECUTE的字符串不需要括号。
  • 使用美元报价的嵌套报价更简单:
  • 在PostgreSQL中插入带单引号的文本
  • 我们可以在子查询中应用ORDER BY,这通常比在外部聚合函数中添加ORDER BY快得多。

相关问题