PostgreSQL
上一頁   下一頁

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)相同。

Outputs

COPY
The copy completed successfully.
ERROR: reason
The copy failed for the reason stated in the error message.

描述

COPY 在 Postgres 表和標準 Unix 文件之間交換數據。COPY 指示 Postgres 後端直接從文件中讀寫數據。該文件必須為後端可見,而且文件名必須從後端的角度聲明。如果聲明的是 stdinstdout,數據通過客戶前端流到後端。

注意

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 本身完成。

每個記錄的實際格式是

<attr1><separator><attr2><separator>...<separator><attrn><newline>
    

如果聲明了 WITH OIDST,它將被放在每行的開頭。

如果 COPY 將它的輸出輸出到標準輸出而不是一個文件,它將在每個換行符前輸出一個反斜杠("\")和一個句點(".")作為行間隔。類似,如果 COPY 從標準輸入讀入數據,它將把一行開頭的由一個反斜杠("\")和一個句點(".")和一個換行符組成的這三個連續字符作為文件結束符。不過,如果在這三個字符組合之前碰到一個真的EOF(文件結束符) COPY 將結束 terminate (接著就是後端自身)。

反斜杠有其他的含義。NULL屬性輸出為"\N"。 一個反斜杠字符輸出成兩個連續的反斜杠 ("\\")一個tab字符用一個反斜杠後面跟一個tab代表。 一個新行字符用一個反斜杠和一個新行代表。當裝載不是由Postgres 產生的文件時,你需要將反斜杠字符 ("\")轉換成雙反斜杠("\\")以保証正確裝載。(出於兼容性考慮,順序的 "\N" 將總是被解釋成一個反斜杠和一個 "N"。更通用的解決方法是 "\\N"。)

二進制格式

當使用 COPY BINARY,文件的頭四個字節將是文件中記錄的個數。如果數值是零, COPY BINARY 命令將一直讀到文件尾。否則,它將在達到個數時停止讀取。文件中剩餘的數據將被忽略。

文件中每一實例的格式如下表。要注意本格式一定要 完全 符合。無符號的四字節整數數量在下表中稱做 uint32 。

表 14-1. 二進制拷貝文件的內容

文件開始
uint32 記錄個數
每條記錄
uint32 記錄數據總長
uint32 oid (如果聲明了)
uint32 null 字段的個數
[uint32,...,uint32] 字段個數(attribute numbers of attributes), 從0開始
- <字段數據>

二進制數據的對齊

在Sun-3s,2-字節字段以2-字節為界對齊,而所有整數字段以4-字節為界對齊。字符字段以1-字節為界對齊。在大部分其他機器上,所有大於1字節的整數是按照4-字節為邊界對齊的。注意,變長字段由字段長度在前﹔數組只是簡單的數組元素型態的連續流。

用法

下面的例子將一個表拷貝到標準輸出,使用豎直條("|")作為域分隔符:

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 語句。


上一頁 首頁 下一頁
COMMIT 開頭 CREATE AGGREGATE