Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1454870
  • 博文数量: 704
  • 博客积分: 10140
  • 博客等级: 上将
  • 技术积分: 6230
  • 用 户 组: 普通用户
  • 注册时间: 2010-07-15 20:41
文章分类

全部博文(704)

文章存档

2013年(1)

2012年(16)

2011年(536)

2010年(151)

分类:

2011-03-01 15:42:44

COPY 
拷贝 
COPY — 在表和文件之间拷贝数据 
语法 
COPY [ BINARY ] table [ WITH OIDS ] 
FROM { 'filename' | stdin } 
[ [USING] DELIMITERS 'delimiter' ] 
[ WITH NULL AS 'null string' ] 
COPY [ BINARY ] table [ WITH OIDS ] 
TO { 'filename' | stdout } 
[ [USING] DELIMITERS 'delimiter' ] 
[ WITH NULL AS 'null string' ] 
输入 
BINARY  
改变字段格式属性,强制所有数据都使用二进制格式存储和读取  

table  
现存表的名字  
WITH OIDS  
拷贝每行的内部唯一对象标识(OID)  
filename  
输入或输出的Unix文件的绝对路径(文件)名  
stdin  
声明输入是来自管道还是终端  
stdout  
声明输出是进入管道还是终端  
delimiter  
一个用于分隔输入或输出的域的分隔符  
null print  
一个代表 NULL 值的字串。因历史原因,缺省是“\N”(反斜杠-N)。例如,你可以自己挑一个空字串。  
注意:对于拷贝入(copy in),任何匹配这个字串的字串将被存储为 NULL 值,所以你应该确保你用的字串和拷贝出(copy out)相同。 
输出 
COPY  
拷贝成功完成  
ERROR: reason  
拷贝失败,原因在错误信息里  

描述 
COPY 在 Postgres 表和标准 Unix 文件之间交换数据COPY 指示 Postgres 后端直接从文件中读写数据该文件必须为后端可见,而且文件名必须从后端的角度声明如果声明的是 stdin 或 stdout,数据通过客户前端流到后端  
注意 
BINARY 关键字将强制使用二进制对象而不是文本存储/读取所有数据这样做在一定程度上比传统的拷贝命令快,但移植性不是很好,而且生成的文件也较大,尽管这个方面与数据本身密切相关  
缺省地,文本拷贝使用 tab ("\t")字符作为分隔符分隔符仍然可以用关键字 USING DELIMITERS 改成任何其它的字符在数据中碰巧与分隔符相同的字符将用引号引起  

你对任何要 COPY 出来的数据必须有select权限,对任何要 COPY 入数据的表必须有inser和update权限使用 COPY 时后端同样需要适当的对文件操作的 Unix 权限  

关键字 USING DELIMITERS 声明一个作为所有列的分隔符的字符如果在分隔符字串里声明了多个字符,只使用第一个字符  

小技巧: 不要把 COPY 和 psql 的命令\copy 混淆 
COPY 不会激活规则,也不会处理字段缺省值。不过它的确激活触发器。  
COPY 在第一个错误处停下来这些在 COPY FROM 中不应该导致问题,但在 COPY TO 时目的表会部分改变应该在一次失败的拷贝后用 VACUUM 查询做一些清除工作  

因为 Postgres 后端的工作目录通常和用户的工作目录不一样,本地用户向一个文件"foo"(没有附加的路径信息)可能会产生不可预见的结果这时,foo 将生成在 $PGDATA/foo 通常,声明拷贝文件时要加上相对后端服务器的全路径  

作为 COPY 参数声明的文件名必须存在与数据库服务器可访问的地方,不管是在本地硬盘还是在网络文件系统上  

如果使用了一个从一台机器到另一台机器的 TCP/IP 连接,而且声明了目标文件,那么目标文件将会写到后端运行的机器上,而不是用户的机器上 

文件格式 
文本格式 
当不带 BINARY 选项使用 COPY TO 时,生成的文件每条记录占据一行,每列(字段)用分隔符分开内嵌的分隔符字符将由一个反斜杠("\")开头字段值本身是由与每个字段类型相关的输出函数生成的字符串某一类型的输出函数本身不应该生成反斜杠;这个任务由 COPY 本身完成  
每个记录的实际格式是  

... 
如果声明了 WITH OIDST,它将被放在每行的开头  
如果 COPY 将它的输出输出到标准输出而不是一个文件,在拷贝结束时,它将在一个新行上输出一个反斜杠("\")和一个句点("."),最后是一个换行符做为文件结束符类似,如果 COPY 从标准输入读入数据,它将把一行开头的由一个反斜杠("\")和一个句点(".")和一个换行符组成的这三个连续字符作为文件结束符不过,如果在这三个字符组合之前碰到一个真的EOF(文件结束符) COPY 将结束 terminate (接着就是后端自身)  

斜杠有其他的含义NULL属性输出为"\N" 一个反斜杠字符输出成两个连续的反斜杠("\\")一个tab字符用一个反斜杠后面跟一个tab代表 一个新行字符用一个反斜杠和一个新行代表当装载不是由Postgres 生成的文件时,你需要将反斜杠字符 ("\")转换成双反斜杠("\\")以保证正确装载?/div>  

二进制格式 
当使用 COPY BINARY,文件的头四个字节将是文件中记录的个数如果数值是零, COPY BINARY 命令将一直读到文件尾否则,它将在达到个数时停止读取文件中剩余的数据将被忽略  
文件中每一实例的格式如下表要注意本格式一定要 完全 符合无符号的四字节整数数量在下表中称做 uint32   

表 19-1. 二进制拷贝文件的内容  

文件开始  
uint32 记录个数  
每条记录  
uint32 记录数据总长  
uint32 oid (如果声明了)  
uint32 null 字段的个数  
[uint32,...,uint32] 字段个数(attribute numbers of attributes), 从0开始  
- <字段数据>  

二进制数据的对齐 
在Sun-3s,2-字节字段以2-字节为界对齐,而所有整数字段以4-字节为界对齐字符字段以1-字节为界对齐在大部分其他机器上,所有大于1字节的整数是按照4-字节为边界对齐的注意,变长字段由字段长度在埃皇 橹皇羌虻サ氖 樵 乩嘈偷牧 鳎?/div>  
用法 
下面的例子将一个表拷贝到标准输出,使用竖直条("|")作为域分隔符:  
COPY country TO stdout USING DELIMITERS '|'; 
从一个 Unix 文件中拷贝数据到表 "country":  
COPY country FROM '/usr1/proj/bray/sql/country_data'; 
这里是一些可以从标准输入 stdin 输入的数据的例子(所以在最后有结束符):  

AF      AFGHANISTAN 
AL      ALBANIA 
DZ      ALGERIA 
... 
ZM      ZAMBIA 
ZW      ZIMBABWE 
\. 
同样的数据,输出到一个Linux/i586机器的二进制文件中去数据是用 Unix 应用 od -c 显示的表里有三个域;第一个是char(2) 第二个是 text所有记录在第三字段有空(null)值注意 char(2) 字段是如何用空(null)补齐成四个字节的以及text字段是如何前面补长度的:  
355  \0  \0  \0 027  \0  \0  \0 001  \0  \0  \0 002  \0  \0  \0 
006  \0  \0  \0   A   F  \0  \0 017  \0  \0  \0   A   F   G   H 
A   N   I   S   T   A   N 023  \0  \0  \0 001  \0  \0  \0 002 
\0  \0  \0 006  \0  \0  \0   A   L  \0  \0  \v  \0  \0  \0   A 
L   B   A   N   I   A 023  \0  \0  \0 001  \0  \0  \0 002  \0 
\0  \0 006  \0  \0  \0   D   Z  \0  \0  \v  \0  \0  \0   A   L 
G   E   R   I   A 
...              \n  \0  \0  \0   Z   A   M   B   I   A 024  \0 
\0  \0 001  \0  \0  \0 002  \0  \0  \0 006  \0  \0  \0   Z   W 
\0  \0  \f  \0  \0  \0   Z   I   M   B   A   B   W   E 
兼容性 
SQL92 
在SQL92里没有 COPY 语句


我刚用到的一条命令如下:

snprintf(m_pSQL, sizeof(m_pSQL) - 1, "COPY %s (customer_id, time, log_type, cmd_seq_no, log_status, log_desc) FROM '%s' USING DELIMITERS ' ';", SiteTableName, StrSrcFileName);




阅读(1453) | 评论(1) | 转发(0) |
给主人留下些什么吧!~~

chinaunix网友2011-03-06 16:58:05

很好的, 收藏了 推荐一个博客,提供很多免费软件编程电子书下载: http://free-ebooks.appspot.com