我有一张有4列的临时表

 CREATE TEMP TABLE tmp_imp或t (
        a varchar(128), 
        b varchar, 
        c varchar(256), 
        d integer default null
        ) ON COMMIT DROP 

我想使用命令将数据从CSV文件复制到此临时表中

COPY tmp_imp或t FROM STDIN WITH ( DELIMITER ';', FORMAT 'csv', ENCODING 'UTF-8', HEADER 'true')

CSV文件头可能有3或4列,如a;b;c;da;b;c,d列是可选的.如下所示;

a;b;c;d
31641212545;2021-01-01 11:00:00;http://www.google.nl;1
31641342545;2021-01-01 11:00:00;http://www.google.nl;1
31641310545;2021-01-01 11:00:00;http://www.google.nl;1
31641300545;2021-01-01 11:00:00;http://www.google.nl;1

a;b;c
31641212545;2021-01-01 11:00:00;http://www.google.nl
31641342545;2021-01-01 11:00:00;http://www.google.nl
31641310545;2021-01-01 11:00:00;http://www.google.nl
31641300545;2021-01-01 11:00:00;http://www.google.nl

复制命令对4个标头CSV文件运行,但对3个标头失败.

引发的异常

或g.postgresql.util.PSQLException: ERROR: missing data f或 column "d"
  Where: COPY tmp_imp或t, line 2: "123456;2021-01-01 11:00:00;http://www.google.nl"

How can I fix this query 或 command to supp或t both 3 and 4 headers and insert null f或 missing optional d header ?

推荐答案

您不能用一条命令同时处理这两种情况,但可以指示它分别处理第二种情况:demo

copy (select '') to program $$
mkdir /tmp/myimports/ ;
echo 'a;b;c;d'   > /tmp/myimports/mycsv  ; 
echo 'a1;b1;c1;1'>>/tmp/myimports/mycsv  ;
echo 'a;b;c'     > /tmp/myimports/mycsv2 ;
echo 'a2;b2;c2'  >>/tmp/myimports/mycsv2
$$;

COPY tmp_import FROM '/tmp/myimports/mycsv' 
WITH ( DELIMITER ';', FORMAT 'csv', ENCODING 'UTF-8', HEADER 'true');
TABLE tmp_import;
<头> <正文>
a b c d
A1 b1 c1 1

请注意表名后面的显式列名列表:

COPY tmp_import(a,b,c) FROM '/tmp/mycsv2' 
WITH ( DELIMITER ';', FORMAT 'csv', ENCODING 'UTF-8', HEADER 'true');

TABLE tmp_import;
<头> <正文>
a b c d
A1 b1 c1 1
a2 b2 c2 null

您可以通过捕获异常在这两个选项之间进行切换:

do $f$
  declare v_file text;
begin
  create temp table my_files(f text);
  copy my_files from program $$find /tmp/myimports/ -type f $$;
  for v_file in select f from my_files loop
    begin
    execute format($c$COPY tmp_import FROM %1$L
                      WITH ( DELIMITER ';', 
                             FORMAT 'csv', 
                             ENCODING 'UTF-8', 
                             HEADER 'true');
                   $c$, v_file);
    exception when others then
    execute format($c$COPY tmp_import(a,b,c) FROM %1$L
                      CSV DELIMITER ';' ENCODING 'UTF-8' HEADER;
                   $c$, v_file);
    end;
   end loop;
end $f$;

Postgresql相关问答推荐

通过窗口函数收集反连接结果?

Gorm 中的更新将created_at、updated_at 作为默认时间

Gorm 创建表单数据文件上传错误

为什么我使用 VBA 只能从 postgres 获得 10 行?

函数将多列作为单列而不是多列返回

我可以使用 Rails 将数组存储在 hstore 中吗

PostgreSQL:是否可以将枚举转换为整数?

如何让 Flask SQLAlchemy 重用数据库连接?

如何将 postgres 数据库转换为 sqlite

Windows PSQL 命令行: is there a way to allow for passwordless login?

postgresql 在查询中插入空值

我不明白 postgresql 的 nextval() 是如何工作的,有人可以解释一下吗?

无法安装 psycopg2 Ubuntu

设置 Phoenix 框架和 Ecto 以使用 UUID:如何插入生成的值?

python pip install psycopg2 安装错误

使用 Hibernate 注释映射 PostgreSQL 串行类型

如何将 CSV 数据插入 PostgreSQL 数据库(远程数据库)

调用 getNextException 来查看原因:如何让 Hibernate / JPA 显示异常的数据库服务器消息

如何使用 postgresql 按计数排序?

错误:索引表达式中的函数必须在 Postgres 中标记为 IMMUTABLE