Postgresql COPY空字符串为NULL无效

Hie*_*ien 2 string postgresql null copy psql

我有一个带有一些整数列的CSV文件,现在它保存为""(空字符串).

我想将它们复制到一个表为NULL值.

使用JAVA代码,我尝试了这些:

String sql = "COPY " + tableName + " FROM STDIN (FORMAT csv,DELIMITER ',',  HEADER true)";
String sql = "COPY " + tableName + " FROM STDIN (FORMAT csv,DELIMITER ',', NULL ''  HEADER true)";
Run Code Online (Sandbox Code Playgroud)

我得到:PSQLException:错误:类型为numeric的输入语法无效:""

String sql = "COPY " + tableName + " FROM STDIN (FORMAT csv,DELIMITER ',', NULL '\"\"'  HEADER true)";
Run Code Online (Sandbox Code Playgroud)

我得到:PSQLException:错误:CSV引号字符不得出现在NULL规范中

以前有人这样做过吗?

Erw*_*ter 10

我假设你知道数字数据类型没有"空字符串"('')的概念.它可以是数字或NULL(或"NaN"表示numeric- 但不适用于integeret al.)

看起来像是从字符串数据类型导出,text并且在那里有一些实际的空字符串 - 现在表示为""- "QUOTECSV格式的默认字符.

NULL将由代表什么,甚至没有报价.手册:

NULL

指定表示空值的字符串.默认值为\N (反斜杠-N)文本格式,以及CSV格式的未加引号的空字符串.

无法定义""通常表示,NULL因为它已经表示空字符串.会模棱两可.

要修复,我看到两个选项:

  1. 在送入之前编辑CSV文件/流,COPY并在没有任何内容的情况下替换"" .如果你在那里有实际的空字符串 - 或者在字符串中""转义文字,可能会很棘手".

  2. (我会做什么.)导入到具有相同结构的辅助临时表,除了integer转换为的列text.然后INSERT(或UPSERT?)从那里到目标表,在integer运行中正确转换值:

-- empty temp table with identical structure
CREATE TABLE tbl_tmp AS TABLE tbl LIMIT 0;

-- ... except for the int / text column
ALTER TABLE tbl_tmp ALTER col_int TYPE text;

COPY tbl_tmp ...;

INSERT INTO tbl  -- identical number and names of columns guaranteed
SELECT col1, col2, NULLIF(col_int, '')::int  -- list all columns in order here
FROM   tbl_tmp;
Run Code Online (Sandbox Code Playgroud)

临时表会在会话结束时自动删除.如果在同一会话中多次运行,则只需截断现有临时表或在每次事务后删除它.

有关:

  • 起初我不相信选项2。然后,我看到是埃尔文 (2认同)

Err*_*rri 8

从 Postgres 9.4 开始,您现在可以使用 FORCE NULL。这会导致空字符串转换为 NULL。非常方便,尤其是 CSV 文件。

语法如下: COPY table FROM '/path/to/file.csv' WITH (FORMAT CSV, DELIMITER ';', FORCE_NULL (columnname));

文档中解释了更多详细信息:https : //www.postgresql.org/docs/current/sql-copy.html

  • 选项 `FORCE_NULL` **带有下划线**,并且应该在“WITH (...)”子句中指定。例如:`COPY table FROM '/path/to/file.csv'WITH (FORMAT CSV, DELIMITER ';', FORCE_NULL (field1, field2, field3));` (5认同)

归档时间:

查看次数:

6546 次

最近记录:

6 年,6 月 前