Postgresql PL/pgSQL从表中动态复制数据
我正在尝试编写一些SQL,以便根据信息模式中的内容从给定数据库中的所有PostgreSQL表复制数据。它应该将数据文件输出到我的本地计算机,以便导入到另一台计算机。最后,我将对此进行调整,以便只转储表的部分(我正在转储的一些表有数百万条记录,我只需要一小部分数据用于测试目的) 这是我到目前为止所拥有的Postgresql PL/pgSQL从表中动态复制数据,postgresql,plpgsql,postgresql-9.4,string-interpolation,Postgresql,Plpgsql,Postgresql 9.4,String Interpolation,我正在尝试编写一些SQL,以便根据信息模式中的内容从给定数据库中的所有PostgreSQL表复制数据。它应该将数据文件输出到我的本地计算机,以便导入到另一台计算机。最后,我将对此进行调整,以便只转储表的部分(我正在转储的一些表有数百万条记录,我只需要一小部分数据用于测试目的) 这是我到目前为止所拥有的 --Copy all tables... DO $$ DECLARE formatstring text; rec record; BEGIN RAISE NOTICE '
--Copy all tables...
DO
$$
DECLARE
formatstring text;
rec record;
BEGIN
RAISE NOTICE 'Copying tables...';
formatstring = 'COPY (select * from %I) to ''C:\Media\Code\%s.csv'';';
FOR rec IN
select table_name from information_schema.tables where table_schema = 'public' order by table_name
LOOP
RAISE NOTICE 'Table: %', rec.table_name;
RAISE NOTICE format(formatstring, rec.table_name, rec.table_name);
EXECUTE format(formatstring, rec.table_name, rec.table_name);
END LOOP;
END;
$$
LANGUAGE plpgsql;
然而,我得到了这个例外
单引号的转义似乎很好(已经检查了这个问题:)。事实上,我可以执行以下操作,并在格式中插入文本:
select format('COPY (select * from %I) to ''C:\Media\Code\%s.csv'';', 'system_user', 'system_user');
有人能帮助解决这个问题吗?我可以很容易地编写一个脚本或代码来为我生成复制命令,但如果能在一个简单的SQL语句中完成这一切,那就太好了。原因是您的3nd
RAISE
语句中存在语法错误。有,但不能直接将表达式馈送到RAISE
。它必须是字符串文字-带有字符串插值选项
在做这件事的同时,我也会简化一些其他事情:
DO
$do$
DECLARE
_formatstring text := $$COPY %1$I TO 'C:\Media\Code\%1$s.csv'$$;
_sql text;
_tbl text;
BEGIN
RAISE NOTICE 'Copying tables...';
FOR _tbl IN
SELECT table_name
FROM information_schema.tables
WHERE table_schema = 'public'
ORDER BY table_name
LOOP
_sql := format(_formatstring, _tbl);
RAISE NOTICE 'Table: %', _tbl;
RAISE NOTICE '%', _sql; -- fixed!!
EXECUTE _sql;
END LOOP;
END
$do$ LANGUAGE plpgsql;
要点
- 使用而不是
中选择*李>的普通表名从tbl
- 嵌套的使用李>
- 格式说明符函数,所以我们只需要提供一次表名李>
- 您可以在声明时分配变量李>
- 标量变量,而不是
循环中的FOR
——我们只需要一列记录
DO
$do$
DECLARE
_formatstring text := $$COPY %1$I TO 'C:\Media\Code\%1$s.csv'$$;
_sql text;
_tbl text;
BEGIN
RAISE NOTICE 'Copying tables...';
FOR _tbl IN
SELECT table_name
FROM information_schema.tables
WHERE table_schema = 'public'
ORDER BY table_name
LOOP
_sql := format(_formatstring, _tbl);
RAISE NOTICE 'Table: %', _tbl;
RAISE NOTICE '%', _sql; -- fixed!!
EXECUTE _sql;
END LOOP;
END
$do$ LANGUAGE plpgsql;