我正在尝试执行以下动态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比较陌生。
答案 0 :(得分:1)
Like a_horse commented,EXECUTE
不是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
快得多。