COPY
COPY — 在文件和表之间复制数据
大纲
COPYtable_name[ (column_name[, ...] ) ] FROM { 'filename' | PROGRAM 'command' | STDIN } [ [ WITH ] (option[, ...] ) ] [ WHEREcondition] COPY {table_name[ (column_name[, ...] ) ] | (query) } TO { 'filename' | PROGRAM 'command' | STDOUT } [ [ WITH ] (option[, ...] ) ] 其中option可以是下列之一: FORMATformat_nameFREEZE [boolean] DELIMITER 'delimiter_character' NULL 'null_string' DEFAULT 'default_string' HEADER [boolean|integer| MATCH ] QUOTE 'quote_character' ESCAPE 'escape_character' FORCE_ARRAY [boolean] FORCE_QUOTE { (column_name[, ...] ) | * } FORCE_NOT_NULL { (column_name[, ...] ) | * } FORCE_NULL { (column_name[, ...] ) | * } ON_ERRORerror_actionREJECT_LIMITmaxerrorENCODING 'encoding_name' LOG_VERBOSITYverbosity
描述
COPY 在
PostgreSQL 表与标准文件系统文件之间传输数据。COPY TO 将表的内容复制到文件,而 COPY FROM
则将数据从文件复制到表中(追加到表中已有的数据之后)。COPY TO 也可以复制
SELECT 查询的结果。
如果指定了列列表,COPY TO 只会将指定列中的数据复制到文件。对于 COPY FROM,文件中的每个字段会按顺序插入到指定列中。未在 COPY FROM 列列表中指定的表列将接收其默认值。
带文件名的 COPY 会指示
PostgreSQL 服务器直接从文件读取或向文件写入。该文件必须可由
PostgreSQL 用户(服务器运行时使用的用户 ID)访问,并且其名称必须从服务器的视角指定。当指定
PROGRAM 时,服务器会执行给定的命令,并从该程序的标准输出读取,或者向该程序的标准输入写入。该命令必须从服务器的视角指定,并且必须可由 PostgreSQL 用户执行。指定
STDIN 或 STDOUT 时,数据通过客户端与服务器之间的连接传输。
每个执行 COPY 的后端进程都会在
pg_stat_progress_copy 视图中报告其进度。有关详细信息,请参见第 27.4.3 节。
默认情况下,COPY 在处理过程中遇到错误会失败。如果希望尽力而为地尝试装载整个文件,可以使用
ON_ERROR 子句指定其他行为。
参数
table_name#一个现有表的名称(可以是模式限定的)。
column_name#要复制的可选列列表。如果没有指定列列表,则会复制该表除生成列之外的所有列。
query#其结果将被复制的
SELECT、VALUES、INSERT、UPDATE、DELETE或MERGE命令。注意查询外层必须带圆括号。对于
INSERT、UPDATE、DELETE和MERGE查询,必须提供RETURNING子句,并且目标关系不能有条件规则,也不能有ALSO规则,也不能有扩展为多个语句的INSTEAD规则。filename#输入或输出文件的路径名。输入文件名可以是绝对路径或相对路径,但输出文件名必须是绝对路径。Windows 用户可能需要使用
E''字符串,并将路径名中的任何反斜线写成双反斜线。PROGRAM#要执行的命令。在
COPY FROM中,输入从该命令的标准输出读取;而在COPY TO中,输出会写入该命令的标准输入。注意该命令由 shell 调用,因此如果需要传递来自不可信来源的参数,必须小心剥离或转义任何可能对 shell 具有特殊含义的字符。出于安全考虑,最好使用固定的命令字符串,至少也应避免在其中包含任何用户输入。
STDIN#指定输入来自客户端应用。
STDOUT#指定输出发送到客户端应用。
boolean#指定所选选项应启用还是关闭。可以写
TRUE、ON或1来启用选项,写FALSE、OFF或0来禁用它。boolean值也可以省略,这种情况下将假定为TRUE。integer#指定传递给所选选项的非负整数值。
FORMAT#选择要读取或者写入的数据格式:
text、csv(逗号分隔值)、json(JavaScript 对象表示法)或者binary。默认是text。详见下文 File Formats。只允许在
COPY TO中使用json选项。注意
在 JSON 格式中,SQL
NULL值会输出为 JSONnull。不过,值本身就是 JSON 字面量null的 JSON 或 JSONB 列也会输出为null,因此在COPY输出中这两种情况无法区分。例如:COPY (SELECT j FROM (VALUES ('null'::json), (NULL::json)) v(j)) TO stdout (FORMAT JSON); {"j":null} {"j":null}FREEZE#请求在复制数据时就将行冻结,就像运行
VACUUM FREEZE命令之后那样。这是为初始数据装载设计的一个性能选项。只有当被装载的表已在当前子事务中创建或截断、该事务中没有打开的游标,并且该事务没有持有更旧的快照时,行才会被冻结。目前无法在分区表或外部表上执行COPY FREEZE。此选项仅允许在COPY FROM中使用。注意,一旦成功装载,所有其他会话都将立即能够看到这些数据。这违背了 MVCC 可见性的常规规则,使用该选项的用户应当了解这可能导致的潜在问题。
DELIMITER#指定分隔文件中每一行(记录)内各列的字符。文本格式中默认是一个制表符,而
CSV格式中默认是一个逗号。这必须是一个单一的单字节字符。使用binary或json格式时不允许这个选项。NULL#指定表示一个空值的字符串。文本格式中默认是
\N(反斜线 -N),CSV格式中默认是一个未加引用的空串。在你不想区分空值和空串的情况下,即使在文本格式中你也可能更喜欢空串。使用binary或json格式时不允许这个选项。注意
在使用
COPY FROM时,任何匹配此字符串的数据项都会被存储为空值,因此应确保这里使用的字符串与COPY TO时使用的相同。DEFAULT#指定表示默认值的字符串。每次在输入文件中发现该字符串时,都会使用对应列的默认值。此选项仅允许用于
COPY FROM,且不能使用binary或json格式。HEADER#在输出时,如果此选项设置为
true(或等效的布尔值),输出的第一行会包含表中的列名。0和1可接受为布尔值,但其他整数不允许用于COPY TO命令。在输入时,如果此选项设置为
true(或等效的布尔值),输入的第一行会被丢弃。如果此选项设置为非负整数,则会丢弃相应数量的行。如果设置为MATCH,则会丢弃第一行,且它必须包含与表列名在数量和顺序上完全匹配的列名;否则会报错。MATCH值仅对COPY FROM命令有效。使用
binary或json格式时不允许此选项。QUOTE#指定在对数据值加引号时使用的引用字符。默认是双引号。这必须是一个单一的单字节字符。只有使用
CSV格式时才允许这个选项。ESCAPE#指定在与
QUOTE值匹配的数据字符之前应出现的字符。默认值与QUOTE值相同(这样当引用字符出现在数据中时,就会被双写)。这必须是一个单一的单字节字符。只有使用CSV格式时才允许这个选项。FORCE_ARRAY#强制在输出开始和结束处使用方括号作为数组装饰,并在各行之间加上逗号。此选项仅允许在
COPY TO中使用,并且只在使用json格式时有效。默认值是false。FORCE_QUOTE#强制对每个指定列中的所有非
NULL值使用引号。NULL输出永远不会加引号。如果指定了*,则所有列中的非NULL值都会加引号。此选项仅允许用于COPY TO,且只能在使用CSV格式时使用。FORCE_NOT_NULL#不要将指定列的值与空值串进行匹配。在空值串就是空串的默认情况下,这意味着空串将被读作长度为零的字符串而不是空值(即使它们没有被引用)。如果指定了
*,该选项会应用到所有列。只有在COPY FROM中使用CSV格式时才允许这个选项。FORCE_NULL#将指定列的值与空值串匹配,即使它已经被加上引号;如果找到匹配,就将该值设为
NULL。在空值串就是空串的默认情况下,这会把一个带引号的空串转换为NULL。如果指定了*,该选项会应用到所有列。只有在COPY FROM中使用CSV格式时才允许这个选项。ON_ERROR#指定在将列输入值转换为其数据类型时遇到错误的处理方式。
error_action为stop时表示使命令失败;而ignore表示丢弃当前输入行并继续处理下一行,而set_null表示把包含无效输入值的字段替换为 NULL 值并继续处理下一字段。默认值是stop。ignore和set_null仅适用于COPY FROM,且FORMAT为text或csv的情况。如果
ON_ERROR设置为ignore或set_null,则在COPY FROM命令结束时会发出一条NOTICE消息,包含被忽略或被更改的行数,只要至少影响了一行。当
LOG_VERBOSITY选项设置为verbose时,对于ignore选项,每丢弃一行都会发出一条NOTICE消息,其中包含输入文件中的行号以及输入转换失败的列名;对于set_null选项,每次输入转换失败都会发出一条NOTICE消息,其中包含输入文件中的行号以及值被替换为NULL的列名。当其设为silent时,不会发出任何关于输入转换失败行的消息。REJECT_LIMIT#当
ON_ERROR设置为ignore时,指定将列输入值转换为其数据类型时可容忍的最大错误数。如果输入导致的错误数超过该值,即使设置了ON_ERROR=ignore,COPY命令也会失败。该子句必须与ON_ERROR=ignore一起使用,并且maxerror必须是正的bigint。若未指定,则ON_ERROR=ignore允许无限个错误,也就是COPY会跳过所有出错数据。ENCODING#指定文件采用
encoding_name编码。如果省略此选项,将使用当前客户端编码。详见下文注解。LOG_VERBOSITY#指定
COPY命令发出消息的详细程度:default、verbose或silent。如果指定verbose,处理过程中会发出额外消息;silent会抑制verbose和默认消息。目前该选项用于
COPY FROM且ON_ERROR设置为ignore或set_null的场景。WHERE#可选的
WHERE子句的一般形式是:WHERE
condition其中
condition是任意求值结果为boolean的表达式。任何不满足该条件的行都不会被插入到表中。如果用实际行值替换所有变量引用后该表达式返回 true,则该行满足该条件。目前,
WHERE表达式中不允许使用子查询、系统列和生成列,并且求值时看不到COPY自身所做的任何更改(当表达式包含对VOLATILE函数的调用时,这一点很重要)。
输出
成功完成时,COPY 命令会返回形如
COPY count
的命令标签。count 为复制的行数。
注意
只有当命令既不是 COPY ... TO STDOUT,也不是等效的
psql 元命令\copy ... to stdout 时,psql 才会打印这个命令标签。这是为了避免将命令标签与刚刚输出的数据混淆。
注解
COPY TO 可用于普通表、已填充的物化视图和分区表。对于非分区表,COPY table
复制的行与
SELECT * FROM ONLY
相同。对于分区表,它复制的行与 tableSELECT * FROM 相同。但它不直接支持其他关系类型,如继承子表或视图。要复制这类关系的全部行,请使用
tableCOPY (SELECT * FROM 。
table) TO
COPY FROM 可用于普通表、外部表、分区表,以及具有
INSTEAD OF INSERT 触发器的视图。
你必须对 COPY TO 读取其值的表具有
SELECT 权限,并对 COPY FROM
插入其值的表具有 INSERT 权限。对于命令中列出的列,具有列级权限即可。
如果对表启用了行级安全,相关的 SELECT 策略将应用于
COPY
语句。目前,对启用了行级安全的表不支持 table TOCOPY FROM。请改用等效的 INSERT 语句。
COPY 命令中指定的文件由服务器而非客户端应用直接读取或写入。因此,这些文件必须位于数据库服务器所在机器上,或者可由数据库服务器访问,而不是仅由客户端访问。它们必须可由 PostgreSQL 用户(服务器运行时使用的用户 ID)访问,并且对该用户可读或可写。同样,使用 PROGRAM 指定的命令也是由服务器而非客户端应用直接执行,因而必须可由 PostgreSQL 用户执行。只有数据库超级用户,或被授予 pg_read_server_files、pg_write_server_files 或
pg_execute_server_program 之一的用户,才允许使用指定文件名或命令的 COPY,因为这允许读取或写入服务器有权访问的任意文件,或者运行服务器有权执行的程序。
不要将 COPY 与
psql 指令
\copy
混淆。\copy 会调用
COPY FROM STDIN 或 COPY TO
STDOUT,然后在 psql 客户端可访问的文件中读取或存储数据。因此,使用\copy 时,文件的可访问性和访问权限取决于客户端而不是服务器。
建议在 COPY 中使用的文件名始终指定为绝对路径。对于 COPY TO,服务器会强制这一点;但对于
COPY FROM,你仍可选择从使用相对路径指定的文件中读取。该路径将相对于服务器进程的工作目录(通常是集簇的数据目录)而非客户端的工作目录进行解释。
使用 PROGRAM 执行命令可能会受到操作系统的访问控制机制(如 SELinux)的限制。
COPY FROM 将调用目标表上的任何触发器和检查约束。但是它不会调用规则。
对于标识列,COPY FROM 命令总会写入输入数据中提供的列值,其行为类似于 INSERT 的
OVERRIDING SYSTEM VALUE 选项。
COPY 的输入和输出会受
DateStyle 影响。为确保数据能移植到其他可能使用非默认
DateStyle 设置的 PostgreSQL
安装中,使用 COPY TO 前应将
DateStyle 设置为 ISO。同样也建议避免在
IntervalStyle 设置为 sql_standard 时转储数据,因为负的 interval 值可能会被采用不同
IntervalStyle 设置的服务器误解。
即使数据会被服务器直接从一个文件读取或者写入一个文件而不通过客户端,输入数据也会被根据 ENCODING 选项或者当前客户端编码解释,并且输出数据会被根据 ENCODING 或者当前客户端编码进行编码。
COPY FROM 在处理过程中会把输入行物理插入表中。如果命令失败,这些行会处于已删除状态;它们不可见,但仍占据磁盘空间。如果在大型复制操作后期失败,这可能造成大量磁盘空间浪费。应使用 VACUUM 回收这些浪费的空间。
FORCE_NULL 和 FORCE_NOT_NULL 可以同时用于同一列。这会把带引号的空值串转换为空值,并把不带引号的空值串转换为空串。
文件格式
文本格式
在使用 text 格式时,读取或写入的是一个文本文件,其中表中的每一行对应文件中的一行。每行中的列由分隔符字符隔开。列值本身是由各属性数据类型的输出函数生成或可被其输入函数接受的字符串。对于为空值的列,会使用指定的空值串代替。如果输入文件中的任何一行包含的列数多于或少于预期,COPY FROM 就会报错。
数据结束可以表示为只包含反斜线加点号(\.)的一行。从文件读取时,并不需要数据结束标记,因为文件结束已经足够;在该上下文中保留这一规定只是为了向后兼容。不过,psql 会使用\.终止
COPY FROM STDIN 操作(即在 SQL 脚本中读取内联
COPY 数据)。在这种情况下,需要这条规则来在脚本结束前终止操作。
在 COPY 数据中,可以使用反斜线字符(\)来转义那些原本可能被当作行或列分隔符的数据字符。特别是,如果下列字符作为列值的一部分出现,那么它们前面必须加一个反斜线:反斜线本身、换行、回车以及当前分隔符字符。
COPY TO 输出指定的空值串时不会添加任何反斜线;相反,COPY FROM 会在去除反斜线之前先将输入与空值串进行匹配。因此,像\N 这样的空值串不会与实际的数据值\N 混淆,因为后者会表示为\\N。
COPY FROM 识别下列特殊的反斜线序列:
| 序列 | 表示 |
|---|---|
\b | 退格 (ASCII 8) |
\f | 换页 (ASCII 12) |
\n | 换行 (ASCII 10) |
\r | 回车 (ASCII 13) |
\t | 制表 (ASCII 9) |
\v | 纵向制表 (ASCII 11) |
\digits | 反斜线后跟一到三个八进制数字表示该数字代码对应的字节 |
\xdigits | 反斜线加 x 后跟一到两个十六进制数字表示该数字代码对应的字节 |
目前,COPY TO 从不会输出八进制或十六进制数字反斜线序列,但对这些控制字符确实会使用上表列出的其他序列。
上表中未提到的其他字符,在前面加了反斜线后仍表示该字符本身。不过,要注意不要不必要地添加反斜线,因为那可能意外地产生与数据结束标记(\.)或空值串(默认是\N)匹配的字符串。这些字符串会在进行任何其他反斜线处理之前先被识别出来。
强烈建议生成 COPY 数据的应用将数据中的换行和回车分别转换为\n 和\r 序列。目前,仍然可以用反斜线加回车表示数据回车,用反斜线加换行表示数据换行。不过,未来版本可能不再接受这些表示方式。如果 COPY 文件在不同机器之间传输(例如从 Unix 到 Windows,或反之),这些表示方式也非常容易被破坏。
所有反斜线序列都在编码转换后进行解释。用八进制和十六进制数字反斜线序列指定的字节必须在数据库编码中形成有效字符。
COPY TO 会用 Unix 风格的换行(“\n”)结束每一行。运行在 Microsoft Windows
上的服务器则会输出回车/换行(“\r\n”),但这只适用于复制到服务器文件的 COPY;为保证跨平台一致性,COPY TO STDOUT 总是发送“\n”,与服务器平台无关。COPY FROM 能够处理以换行、回车或回车/换行结束的行。为减少本应是数据的未加反斜线新行或回车带来的风险,如果输入中的行结束符并不一致,COPY FROM 将会报错。
CSV 格式
这种格式选项用于导入和导出许多其他程序(如电子表格)使用的逗号分隔值(CSV)文件格式。不同于
PostgreSQL 标准文本格式使用的转义规则,它会生成并识别通用的 CSV 转义机制。
每条记录中的值由 DELIMITER 字符分隔。如果某个值包含分隔符字符、QUOTE 字符、NULL 字符串、回车或换行字符,那么整个值都会以前后各一个 QUOTE 字符包围,并且该值内每次出现 QUOTE 字符或 ESCAPE
字符之前都会加上转义字符。对于指定列中的非 NULL 值输出,还可以使用 FORCE_QUOTE 来强制加引号。
CSV 格式没有标准方式区分 NULL 值和空字符串。PostgreSQL 的 COPY 通过引号来处理这一区别。NULL 会按照 NULL 参数字符串输出,且不会被加引号;而与 NULL 参数字符串匹配的非 NULL
值会被加引号。例如,在默认设置下,NULL 会写成一个未加引号的空字符串,而空字符串数据值会写成双引号包围的形式("")。读取值时遵循类似规则。你可以使用 FORCE_NOT_NULL 来阻止对指定列进行 NULL 输入比较。也可以使用 FORCE_NULL
将带引号的空值串数据值转换为 NULL。
因为反斜线在 CSV 格式中不是特殊字符,文本模式下使用的数据结束标记(\.)在读取 CSV 数据时通常不会被特殊处理。但有一个例外:psql 在
COPY FROM STDIN 操作(即在 SQL 脚本中读取内联
COPY 数据)时,只要遇到仅包含\.的一行,就会终止操作,无论当前是文本模式还是 CSV 模式。
注意
PostgreSQL 在 v18 之前的版本中总是将未加引号的
\. 识别为数据结束标记,即使是从独立文件读取时也是如此。为兼容旧版本,COPY TO 仍会在
\. 单独占一行时为其加引号,尽管现在已非必需。
注意
在 CSV 格式中,所有字符都有意义。被空白字符或
DELIMITER 之外其他字符包围的带引号值,会把这些字符也包含进值中。如果你导入的数据来自某个会用空白把 CSV
行填充到固定宽度的系统,这可能导致错误。出现这种情况时,你可能需要在将数据导入 PostgreSQL 之前,先预处理 CSV 文件以移除尾随空白。
注意
CSV 格式既能识别也能生成这样的 CSV 文件:其中带引号的值包含内嵌的回车和换行。因此,这类文件不像文本格式文件那样严格地一行对应表中的一行。
注意
很多程序会生成奇怪、甚至近乎反常的 CSV 文件,因此这种文件格式更像一种约定而非标准。因而你可能会遇到无法用这种机制导入的文件,而 COPY 也可能生成其他程序无法处理的文件。
二进制格式
binary 格式选项会使所有数据以二进制格式而不是文本格式存储或读取。它比文本和 CSV 格式稍快一些,但二进制格式文件在不同的机器架构和 PostgreSQL 版本之间的可移植性较差。此外,二进制格式与数据类型高度相关。例如,不能从
smallint 列输出二进制数据再读入到 integer 列中,尽管这种做法在文本格式下是可行的。
binary 文件格式由文件头、零个或多个包含行数据的元组以及一个文件尾构成。头部和数据都以网络字节序表示。
注意
7.4 之前的 PostgreSQL 版本使用一种不同的二进制文件格式。
文件头
文件头由 19 字节的固定字段构成,后面跟着一个变长的头部扩展区。固定字段有:
- 签名 #
11 字节序列
PGCOPY\n\377\r\n\0— 注意,零字节是签名中必不可少的一部分。(该签名的设计目的是便于识别那些在不具备 8 位透明性的传输过程中遭到破坏的文件。行尾转换过滤器、零字节丢失、高位丢失或奇偶校验变化等情况都会改变该签名。)- 标志字段 #
32 位整数位掩码,用以表示该文件格式的重要方面。位编号从 0(LSB)到 31(MSB)。注意,该字段和此文件格式中使用的所有整数字段一样,都按网络字节序存放(最高有效字节在前)。16 到 31 位保留用于表示严重的文件格式问题;如果读取程序在这个范围内发现意外置位,应该中止。0 到 15 位保留用于表示向后兼容的格式问题;读取程序应简单忽略这个范围内任何意外置位。目前只定义了一个标志位,其余位都必须为零:
- 位 16 #
如果为 1,则数据中包含 OID;如果为 0,则不包含。当前版本的 PostgreSQL 已不再支持 oid 系统列,但该格式仍保留这个指示符。
- 头部扩展区长度 #
32 位整数,表示头部剩余部分的长度(以字节计),不包括该字段本身。当前该值为零,因此其后紧接着第一个元组。未来对这种格式的更改可能允许在头部中包含额外数据。如果读取程序不知道如何处理头部扩展区数据,应静默跳过它。
头部扩展区被设想为包含一系列可自我标识的块。标志字段并不用于告诉读取程序扩展区中包含哪些内容。头部扩展内容的具体设计留待后续版本决定。
这种设计既允许向后兼容的头部新增(增加头部扩展块,或设置低位标志位),也允许不向后兼容的更改(设置高位标志位来表明这类更改,并在需要时向扩展区增加支持数据)。
元组
每个元组都以一个 16 位整数计数开头,用于表示该元组中的字段数。(目前,一个表中的所有元组都应有相同的计数,但这未必永远如此。)随后,对元组中的每个字段,都会有一个 32 位长度字,后跟相应字节数的字段数据。(长度字不包括其本身,且可以为零。)特殊情况下,-1 表示一个 NULL 字段值;在 NULL 情况下,后面不会跟随任何值字节。
字段之间没有对齐填充或任何其他额外数据。
当前,二进制格式文件中的所有数据值都假定为二进制格式(格式代码一)。可以预见,未来的扩展可能会增加一个允许为各列分别指定格式代码的头部字段。
要确定实际元组数据应采用的二进制格式,你应该参考
PostgreSQL 源码,特别是各列数据类型对应的*send 和*recv 函数(这些函数通常可以在源码分发包的 src/backend/utils/adt/目录中找到)。
如果文件中包含 OID,则 OID 字段会紧跟在字段计数字之后。它是一个普通字段,不过不计入字段数。注意,当前版本的 PostgreSQL 不再支持 oid 系统列。
文件尾
文件尾由一个值为 -1 的 16 位整数构成。这很容易与元组的字段计数字区分开来。
如果字段计数字既不是 -1 也不是预期的列数,读取程序应报告错误。这提供了一项额外检查,以防与数据失去同步。
示例
下面的示例使用竖线(|)作为字段分隔符将一个表复制到客户端:
COPY country TO STDOUT (DELIMITER '|');
启用 FORCE_ARRAY 选项时,整个输出会被包裹在一个 JSON 数组中,各行之间以逗号分隔:
COPY (SELECT * FROM (VALUES(1),(2)) val(id)) TO STDOUT (FORMAT JSON, FORCE_ARRAY);
输出如下:
[
{"id":1}
,{"id":2}
]
要将文件中的数据复制到 country 表中:
COPY country FROM '/usr1/proj/bray/sql/country_data';
只把名称以 'A' 开头的国家复制到一个文件中:
COPY (SELECT * FROM country WHERE country_name LIKE 'A%') TO '/usr1/proj/bray/sql/a_list_countries.copy';
要复制到压缩文件中,可以将输出通过管道送入外部压缩程序:
COPY country TO PROGRAM 'gzip > /usr1/proj/bray/sql/country_data.gz';
下面给出适合从 STDIN 复制到表中的示例数据:
AF AFGHANISTAN AL ALBANIA DZ ALGERIA ZM ZAMBIA ZW ZIMBABWE
注意每一行中的空白实际上是一个制表符。
下面是用二进制格式输出的相同数据。该数据是用 Unix 工具
od -c 过滤后显示的。该表具有三列,第一列类型是 char(2),第二列类型是 text,第三列类型是 integer。所有行在第三列都是空值。
0000000 P G C O P Y \n 377 \r \n \0 \0 \0 \0 \0 \0 0000020 \0 \0 \0 \0 003 \0 \0 \0 002 A F \0 \0 \0 013 A 0000040 F G H A N I S T A N 377 377 377 377 \0 003 0000060 \0 \0 \0 002 A L \0 \0 \0 007 A L B A N I 0000100 A 377 377 377 377 \0 003 \0 \0 \0 002 D Z \0 \0 \0 0000120 007 A L G E R I A 377 377 377 377 \0 003 \0 \0 0000140 \0 002 Z M \0 \0 \0 006 Z A M B I A 377 377 0000160 377 377 \0 003 \0 \0 \0 002 Z W \0 \0 \0 \b Z I 0000200 M B A B W E 377 377 377 377 377 377
兼容性
SQL 标准中没有 COPY 语句。
下列语法在 PostgreSQL 9.0 之前的版本中使用,现仍受支持:
COPYtable_name[ (column_name[, ...] ) ] FROM { 'filename' | STDIN } [ [ WITH ] [ BINARY ] [ DELIMITER [ AS ] 'delimiter_character' ] [ NULL [ AS ] 'null_string' ] [ CSV [ HEADER ] [ QUOTE [ AS ] 'quote_character' ] [ ESCAPE [ AS ] 'escape_character' ] [ FORCE NOT NULLcolumn_name[, ...] ] ] ] COPY {table_name[ (column_name[, ...] ) ] | (query) } TO { 'filename' | STDOUT } [ [ WITH ] [ BINARY ] [ DELIMITER [ AS ] 'delimiter_character' ] [ NULL [ AS ] 'null_string' ] [ CSV [ HEADER ] [ QUOTE [ AS ] 'quote_character' ] [ ESCAPE [ AS ] 'escape_character' ] [ FORCE QUOTE {column_name[, ...] | * } ] ] ]
注意在这种语法中,BINARY 和 CSV 被视为独立的关键字,而不是 FORMAT 选项的参数。
下列语法在 PostgreSQL 7.3 之前的版本中使用,现仍受支持:
COPY [ BINARY ]table_nameFROM { 'filename' | STDIN } [ [USING] DELIMITERS 'delimiter_character' ] [ WITH NULL AS 'null_string' ] COPY [ BINARY ]table_nameTO { 'filename' | STDOUT } [ [USING] DELIMITERS 'delimiter_character' ] [ WITH NULL AS 'null_string' ]