首页 > 解决方案 > 在 postgresql 中更新和插入来自 csv 文件的记录

问题描述

我的数据库中有一个表customer,其中已经有一些记录,现在我想从 CSV 文件中对客户表进行增量更改。

以下是我尝试过但不起作用的两种方法:

方法1:

CREATE TEMP TABLE CUSTOMER_TEMP AS
    select * from migration.customer where 1=2;

COPY CUSTOMER_TEMP(CUST_ID,CUST_CONTACT,CUST_COUNTRY,CUST_DETAIL) from 'C:\demo_dir\CUSTOMER_DATA_CHANGE.csv' DELIMITER '|';

MERGE INTO MIGRATION.CUSTOMER t
    USING(SELECT * FROM CUSTOMER_TEMP) AS m
        ON t.CUST_ID = m.CUST_ID
    WHEN MATCHED
        UPDATE SET t.CUST_ID = m.CUST_ID, t.CUST_CONTACT = m.CUST_CONTACT, t.CUST_COUNTRY = m.CUST_COUNTRY, t.CUST_DETAIL = m.CUST_DETAIL
    WHEN NOT MATCHED
        INSERT(CUST_ID,CUST_CONTACT,CUST_COUNTRY,CUST_DETAIL)
            VALUES(m.CUST_ID,m.CUST_CONTACT,m.CUST_COUNTRY,m.CUST_DETAIL);

DROP TABLE CUSTOMER_TEMP;

在检查了几个站点后,我知道 PostgreSQL 数据库不支持 Merge 语句。所以我尝试了以下方法来做到这一点:

方法2:

CREATE TEMP TABLE CUSTOMER_TEMP AS
select * from migration.customer where 1=2;

COPY CUSTOMER_TEMP(CUST_ID,CUST_CONTACT,CUST_COUNTRY,CUST_DETAIL) from 'C:\demo_dir\CUSTOMER_DATA_CHANGE.csv' DELIMITER '|';

INSERT INTO MIGRATION.CUSTOMER(CUST_ID,CUST_CONTACT,CUST_COUNTRY,CUST_DETAIL)
    (SELECT T.CUST_ID,T.CUST_CONTACT,T.CUST_COUNTRY,T.CUST_DETAIL FROM CUSTOMER_TEMP AS T)
    on conflict on constraint pk_cust
    do update set CUST_CONTACT = T.CUST_CONTACT, CUST_COUNTRY = T.CUST_COUNTRY, CUST_DETAIL = T.CUST_DETAIL
;

DROP TABLE CUSTOMER_TEMP;

我从上述命令中得到的错误是:

错误:表“t”缺少 FROM 子句条目第 4 行:更新设置 CUST_CONTACT = T.CUST_CONTACT,CUST_COUNTRY =... ^ SQL 状态:42P01 字符:232

但是我在插入命令中遇到错误。

请帮忙,我使用的是 PostgreSQL 11 版本。

标签: sqlpostgresqlcsv

解决方案


您应该使用关键字 EXCLUDED:

CREATE TEMP TABLE CUSTOMER_TEMP (LIKE migration.customer);

COPY CUSTOMER_TEMP(CUST_ID,CUST_CONTACT,CUST_COUNTRY,CUST_DETAIL) from 'C:\demo_dir\CUSTOMER_DATA_CHANGE.csv' DELIMITER '|';

INSERT INTO MIGRATION.CUSTOMER(CUST_ID,CUST_CONTACT,CUST_COUNTRY,CUST_DETAIL)
    (SELECT T.CUST_ID,T.CUST_CONTACT,T.CUST_COUNTRY,T.CUST_DETAIL FROM CUSTOMER_TEMP AS T)
    on conflict on constraint pk_cust
    do update set CUST_CONTACT = EXCLUDED.CUST_CONTACT, CUST_COUNTRY = EXCLUDED.CUST_COUNTRY, CUST_DETAIL = EXCLUDED.CUST_DETAIL
;

DROP TABLE CUSTOMER_TEMP;

推荐阅读