AnalyticDB PostgreSQL版支援COPY ON CONFLICT覆蓋匯入資料。目前COPY ON CONFLICT僅支援全資料表條件約束檢查及全列覆蓋寫入。
在AnalyticDB PostgreSQL版中,您可以通過COPY快速匯入資料,但是在COPY匯入資料的過程中,如果資料與表的約束衝突,COPY任務會報錯並終止。AnalyticDB PostgreSQL提供了COPY ON CONFLICT功能,支援在約束衝突時進行覆蓋寫入或忽略寫入,避免COPY任務因為約束衝突而失敗。
僅核心編譯日期為20210528及以後的AnalyticDB PostgreSQL 6.0版執行個體支援COPY ON CONFLICT功能。為了更好地使用該功能,建議您升級至最新的核心版本,升級核心小版本,請參見版本升級。
使用約束
目標表需為堆表,不支援AO表(AO表不支援唯一索引,所以不支援AO表)。
僅V6.3.6.1及以上核心版本支援目標表為分區表。如何升級核心版本,請參見版本升級。
目標表不支援Updatable View(可更新視圖)。
COPY ON CONFLICT僅支援COPY FROM,不支援COPY TO。
不支援指定約束索引列,COPY ON CONFLICT預設判斷所有約束列。若指定約束索引列,則COPY執行失敗,報錯資訊如下:
COPY NATION FROM stdin DO ON CONFLICT(n_nationkey) DO UPDATE; ERROR: COPY ON CONFLICT does NOT support CONFLICT index params
不支援指定更新列,COPY ON CONFLICT預設更新所有列。若指定更新列,則COPY執行失敗,報錯資訊如下:
COPY NATION FROM stdin DO ON CONFLICT DO UPDATE SET n_nationkey = excluded.n_nationkey; ERROR: COPY ON CONFLICT does NOT support UPDATE SET targets
文法
COPY table [(column [, ...])] FROM {'file' | STDIN}
[ [WITH]
[BINARY]
[OIDS]
[HEADER]
[DELIMITER [ AS ] 'delimiter']
[NULL [ AS ] 'null string']
[ESCAPE [ AS ] 'escape' | 'OFF']
[NEWLINE [ AS ] 'LF' | 'CR' | 'CRLF']
[CSV [QUOTE [ AS ] 'quote']
[FORCE NOT NULL column [, ...]]
[FILL MISSING FIELDS]
[[LOG ERRORS]
SEGMENT REJECT LIMIT count [ROWS | PERCENT] ]
[DO ON CONFLICT DO UPDATE | NOTHING]
COPY ON CONFLICT提供了DO ON CONFLICT DO UPDATE和DO ON CONFLICT DO NOTHING兩個子句:
DO ON CONFLICT DO UPDATE表示資料表條件約束衝突時全列更新。
DO ON CONFLICT DO NOTHING表示資料表條件約束衝突時忽略輸入內容。
樣本
建立一個表NATION,表中包含4列,其中N_NATIONKEY為主鍵列,具有主鍵約束,建表語句如下:
CREATE TABLE NATION ( N_NATIONKEY INTEGER, N_NAME CHAR(25), N_REGIONKEY INTEGER, N_COMMENT VARCHAR(152), PRIMARY KEY (N_NATIONKEY) );
通過COPY匯入部分資料,COPY語句如下:
COPY NATION FROM stdin;
出現>>標誌後逐條輸入如下內容:
0 'ALGERIA' 0 'haggle. carefully final deposits detect slyly agai' 1 'ARGENTINA' 1 'al foxes promise slyly according to the regular accounts. bold requests alon' 2 'BRAZIL' 1 'y alongside of the pending deposits. carefully special packages are about the ironic forges. slyly speci' 3 'CANADA' 1 'eas hang ironic, silent packages. slyly regular packages are furiously over the tithes. fluffily bold' \.
說明複製以上資料時,請將兩列值之間的空格替換為Tab。
查詢NATION表,查看已經匯入的資料,查詢語句如下:
SELECT * from NATION;
返回資訊如下:
n_nationkey | n_name | n_regionkey | n_comment -------------+---------------------------+-------------+------------------------------------------------------------------------------------------------------------ 2 | 'BRAZIL' | 1 | 'y alongside of the pending deposits. carefully special packages are about the ironic forges. slyly speci' 3 | 'CANADA' | 1 | 'eas hang ironic, silent packages. slyly regular packages are furiously over the tithes. fluffily bold' 0 | 'ALGERIA' | 0 | ' haggle. carefully final deposits detect slyly agai' 1 | 'ARGENTINA' | 1 | 'al foxes promise slyly according to the regular accounts. bold requests alon' (4 rows)
使用COPY語句匯入一行主鍵衝突的資料,COPY語句如下:
COPY NATION FROM stdin;
出現>>標誌後逐條輸入如下內容:
0 'GERMANY' 3 'l platelets. regular accounts x-ray: unusual, regular acco' \.
說明複製以上資料時,請將兩列值之間的空格替換為Tab。
此時執行會產生報錯,報錯內容如下:
ERROR: duplicate key value violates unique constraint "nation_pkey" DETAIL: Key (n_nationkey)=(0) already exists. CONTEXT: COPY nation, line 1
使用COPY ON CONFLICT語句,在主鍵衝突的情況下更新資料,COPY ON CONFLICT語句如下:
COPY NATION FROM stdin DO ON CONFLICT DO UPDATE;
出現>>標誌後逐條輸入如下內容:
0 'GERMANY' 3 'l platelets. regular accounts x-ray: unusual, regular acco' \.
說明複製以上資料時,請將兩列值之間的空格替換為Tab。
此時COPY語句不會產生報錯資訊,查詢NATION表可以看到主鍵為0的行資料已更新,查詢語句如下:
SELECT * FROM NATION;
返回資訊如下:
n_nationkey | n_name | n_regionkey | n_comment -------------+---------------------------+-------------+------------------------------------------------------------------------------------------------------------ 2 | 'BRAZIL' | 1 | 'y alongside of the pending deposits. carefully special packages are about the ironic forges. slyly speci' 3 | 'CANADA' | 1 | 'eas hang ironic, silent packages. slyly regular packages are furiously over the tithes. fluffily bold' 1 | 'ARGENTINA' | 1 | 'al foxes promise slyly according to the regular accounts. bold requests alon' 0 | 'GERMANY' | 3 | 'l platelets. regular accounts x-ray: unusual, regular acco' (4 rows)
使用COPY ON CONFLICT功能,在主鍵衝突的情況下,忽略輸入:
COPY NATION FROM stdin DO ON CONFLICT DO NOTHING;
出現>>標誌後逐條輸入如下內容:
1 'GERMANY' 3 'l platelets. regular accounts x-ray: unusual, regular acco' \.
說明複製以上資料時,請將兩列值之間的空格替換為Tab。
此時COPY語句不會產生報錯資訊,查詢NATION表可以看到主鍵為1的行資料沒有更新,查詢語句如下:
SELECT * FROM NATION;
返回資訊如下:
n_nationkey | n_name | n_regionkey | n_comment -------------+---------------------------+-------------+------------------------------------------------------------------------------------------------------------ 2 | 'BRAZIL' | 1 | 'y alongside of the pending deposits. carefully special packages are about the ironic forges. slyly speci' 3 | 'CANADA' | 1 | 'eas hang ironic, silent packages. slyly regular packages are furiously over the tithes. fluffily bold' 1 | 'ARGENTINA' | 1 | 'al foxes promise slyly according to the regular accounts. bold requests alon' 0 | 'GERMANY' | 3 | 'l platelets. regular accounts x-ray: unusual, regular acco' (4 rows)