我有一个sql函数:
CREATE OR REPLACE FUNCTION dump_func()
RETURNS void AS
$BODY$
DECLARE
r record;
loc varchar(100);
BEGIN
for r in (SELECT f.oid as oid, proname, pg_get_functiondef(f.oid) as src
FROM pg_catalog.pg_proc f
INNER JOIN pg_catalog.pg_namespace n ON (f.pronamespace = n.oid)
WHERE n.nspname = 'public') loop
loc = '/Users/raman/Desktop/functions/' || r.proname || '.sql';
raise notice '% - %', r.oid, loc;
raise notice 'func: %', r.src;
EXECUTE format('COPY (
SELECT pg_get_functiondef(f.oid)
FROM pg_catalog.pg_proc f
INNER JOIN pg_catalog.pg_namespace n ON (f.pronamespace = n.oid)
WHERE n.nspname = ''public'' and f.oid=%s
) TO ''%s'' ', r.oid, loc);
end loop;
end
$BODY$
LANGUAGE plpgsql;
使用COPY命令将postgres中的每个db函数导出到一个单独的文件中。一切正常,除了在导出的sql文件中新的行和制表符被转义,例如:
创建或替换函数public.is_numeric(text)\ n RETURNS boolean \ n LANGUAGE plpgsql \ n IMMUTABLE \ nAS $ function $ \ nDECLARE x NUMERIC; \ n \ nBEGIN \ n x = $ 1 :: NUMERIC; \ n返回TRUE; \ n \ nEXEXCEPTION 当其他人返回错误时; \ nEND; \ n $ function $ \ n
正如您可以看到新的行和标签被转义,如何解决?
答案 0 :(得分:0)
实际上,这可以做到。 Hacky虽然只是使用regexp_split_to_table
并在\n
字符上拆分。我只想自己解决同样的问题。这是我编写的代码:
DO $$
DECLARE
v_row record;
v_proname text;
v_sql text;
BEGIN
FOR v_row IN (
SELECT f.proname
FROM pg_catalog.pg_proc AS f
INNER JOIN pg_catalog.pg_namespace AS n ON (f.pronamespace = n.oid)
WHERE n.nspname = 'public' AND f.proisagg = false
) LOOP
SELECT v_row.proname::text INTO v_proname;
EXECUTE FORMAT('COPY (
SELECT regexp_split_to_table(regexp_replace(pg_get_functiondef(oid), ''\t'', '' '', ''g''), ''\n'')
FROM pg_catalog.pg_proc WHERE proname = ''%s'')
TO ''C:\pg\%s.sql'';'
, v_proname, v_proname);
END LOOP;
END $$
答案 1 :(得分:0)
安德鲁的答案是正确的,也帮助我设置了格式。
我想出了一个类似的功能,但是要在PSQL中打印所有用户定义的功能。希望它对需要它的人有所帮助:
CREATE OR REPLACE FUNCTION printFunctions(stage VARCHAR, ischema VARCHAR, file_path VARCHAR)
RETURNS VARCHAR AS
$$
DECLARE
func VARCHAR;
file_location TEXT;
BEGIN
FOR func IN SELECT procname FROM listfunctions()
LOOP
SELECT (file_path || '/' || func || '_' || stage || '.sql') INTO file_location;
IF (SELECT regexp_matches(func, '(pldb|plpg)')) IS NULL
THEN
EXECUTE 'COPY ' ||
'(SELECT regexp_split_to_table(regexp_replace(pg_get_functiondef(oid), ''\t'', '' '', ''g''),''\n'') from pg_proc where proname=' ||
'''' || func || '''' ||
' and pronamespace=(select oid from pg_namespace where nspname=' ||
'''' || ischema || ''''
')) TO ' || '''' || file_location || '''';
END IF;
END LOOP;
RETURN stage;
END
$$
LANGUAGE 'plpgsql';
您可以通过以下方式调用它:
SELECT * FROM printFunctions('dev', 'public', '/tmp');