jli*_*ted 1 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;')
Run Code Online (Sandbox Code Playgroud)
我对 PostgreSQL 比较陌生。
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
Run Code Online (Sandbox Code Playgroud)
我添加了一些改进并简化了嵌套SELECT查询。
添加IF EXISTS到DROP FUNCTION除非您确定该函数存在或者您希望在不存在时引发异常。
DISTINCT在子查询中就足够了,不需要DISTINCT在外部中另一个SELECT。
用于在必要时自动使用quote_ident()双引号标识符。否则,您可能会遇到语法错误和 SQL 注入。
我们提供给 的字符串不需要括号EXECUTE。
使用美元引号进行更简单的嵌套引用:
我们可以在子查询中应用,这通常比在外部聚合函数中ORDER BY添加要快得多。ORDER BY