将 PostgreSQL 表中的特定行导出为 INSERT SQL 脚本

新手上路,请多包涵

我有一个名为 nyummy 的数据库模式和一个名为 cimory 的表:

 create table nyummy.cimory (
  id numeric(10,0) not null,
  name character varying(60) not null,
  city character varying(50) not null,
  CONSTRAINT cimory_pkey PRIMARY KEY (id)
);

我想将 cimory 表的数据导出为插入 SQL 脚本文件。但是,我只想导出城市等于“东京”的记录/数据(假设城市数据都是小写的)。

怎么做?

解决方案是在免费软件 GUI 工具还是命令行中都没有关系(尽管 GUI 工具解决方案更好)。我曾尝试过 pgAdmin III,但找不到执行此操作的选项。

原文由 null 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 1.7k
2 个回答

使用要导出的集合创建一个表,然后使用命令行实用程序 pg_dump 导出到文件:

 create table export_table as
select id, name, city
from nyummy.cimory
where city = 'tokyo'

 $ pg_dump --table=export_table --data-only --column-inserts my_database > data.sql

--column-inserts 将转储为带有列名的插入命令。

--data-only 不要转储模式。

如下所述,在需要新导出时创建视图而不是表将避免创建表。

原文由 Clodoaldo Neto 发布,翻译遵循 CC BY-SA 4.0 许可协议

我试图根据@PhilHibbs 代码以不同的方式编写一个执行此操作的程序。请查看并测试。

  CREATE OR REPLACE FUNCTION dump(IN p_schema text, IN p_table text, IN p_where text)
   RETURNS setof text AS
 $BODY$
 DECLARE
     dumpquery_0 text;
     dumpquery_1 text;
     selquery text;
     selvalue text;
     valrec record;
     colrec record;
 BEGIN

     -- ------ --
     -- GLOBAL --
     --   build base INSERT
     --   build SELECT array[ ... ]
     dumpquery_0 := 'INSERT INTO ' ||  quote_ident(p_schema) || '.' || quote_ident(p_table) || '(';
     selquery    := 'SELECT array[';

     <<label0>>
     FOR colrec IN SELECT table_schema, table_name, column_name, data_type
                   FROM information_schema.columns
                   WHERE table_name = p_table and table_schema = p_schema
                   ORDER BY ordinal_position
     LOOP
         dumpquery_0 := dumpquery_0 || quote_ident(colrec.column_name) || ',';
         selquery    := selquery    || 'CAST(' || quote_ident(colrec.column_name) || ' AS TEXT),';
     END LOOP label0;

     dumpquery_0 := substring(dumpquery_0 ,1,length(dumpquery_0)-1) || ')';
     dumpquery_0 := dumpquery_0 || ' VALUES (';
     selquery    := substring(selquery    ,1,length(selquery)-1)    || '] AS MYARRAY';
     selquery    := selquery    || ' FROM ' ||quote_ident(p_schema)||'.'||quote_ident(p_table);
     selquery    := selquery    || ' WHERE '||p_where;
     -- GLOBAL --
     -- ------ --

     -- ----------- --
     -- SELECT LOOP --
     --   execute SELECT built and loop on each row
     <<label1>>
     FOR valrec IN  EXECUTE  selquery
     LOOP
         dumpquery_1 := '';
         IF not found THEN
             EXIT ;
         END IF;

         -- ----------- --
         -- LOOP ARRAY (EACH FIELDS) --
         <<label2>>
         FOREACH selvalue in ARRAY valrec.MYARRAY
         LOOP
             IF selvalue IS NULL
             THEN selvalue := 'NULL';
             ELSE selvalue := quote_literal(selvalue);
             END IF;
             dumpquery_1 := dumpquery_1 || selvalue || ',';
         END LOOP label2;
         dumpquery_1 := substring(dumpquery_1 ,1,length(dumpquery_1)-1) || ');';
         -- LOOP ARRAY (EACH FIELD) --
         -- ----------- --

         -- debug: RETURN NEXT dumpquery_0 || dumpquery_1 || ' --' || selquery;
         -- debug: RETURN NEXT selquery;
         RETURN NEXT dumpquery_0 || dumpquery_1;

     END LOOP label1 ;
     -- SELECT LOOP --
     -- ----------- --

 RETURN ;
 END
 $BODY$
   LANGUAGE plpgsql VOLATILE;

接着 :

 -- for a range
SELECT dump('public', 'my_table','my_id between 123456 and 123459');
-- for the entire table
SELECT dump('public', 'my_table','true');

在我的 postgres 9.1 上测试,使用混合字段数据类型(文本、双精度、整数、没有时区的时间戳等)的表。

这就是需要 TEXT 类型的 CAST 的原因。我的测试正确运行了大约 9M 行,看起来它在运行 18 分钟之前就失败了。

ps:我在 WEB 上找到了 mysql 的等价物。

原文由 Vi Shen 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进