String Postgresql将空字符串复制为NULL无效

String Postgresql将空字符串复制为NULL无效,string,postgresql,null,copy,psql,String,Postgresql,Null,Copy,Psql,我有一个带有整数列的CSV文件,现在它保存为“”(空字符串) 我想将它们作为空值复制到表中 使用JAVA代码,我尝试了以下方法: String sql = "COPY " + tableName + " FROM STDIN (FORMAT csv,DELIMITER ',', HEADER true)"; String sql = "COPY " + tableName + " FROM STDIN (FORMAT csv,DELIMITER ',', NULL '' HEADER tru

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

我想将它们作为空值复制到表中

使用JAVA代码,我尝试了以下方法:

String sql = "COPY " + tableName + " FROM STDIN (FORMAT csv,DELIMITER ',',  HEADER true)";
String sql = "COPY " + tableName + " FROM STDIN (FORMAT csv,DELIMITER ',', NULL ''  HEADER true)";
I get:PSQLException:错误:类型numeric的输入语法无效:“”

I get:PSQLException:ERROR:CSV引号字符不能出现在NULL规范中


以前有人这样做过吗?

我假设您知道数字数据类型没有“空字符串”的概念(
'
)。它要么是一个数字,要么是空的(或表示
数值的'NaN',但不表示
整数等。)

看起来您是从字符串数据类型(如
text
)导出的,其中有一些实际的空字符串-现在表示为
-
是CSV格式的默认
引号
字符

NULL将由零表示,甚至连引号都不表示

NULL

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

无法定义
以通常表示
NULL
,因为它已经表示空字符串。这将是不明确的

要解决此问题,我看到两个选项:

  • 在馈送到
    COPY
    之前编辑CSV文件/流,并将“”替换为nothing。如果其中也有实际的空字符串,或者
    在字符串中转义文本
    ,则可能会很棘手

  • (我要做的)导入到一个具有相同结构的辅助临时表,除了转换为
    文本的
    整数
    列之外。然后将
    INSERT
    (或UPSERT?)插入到目标表中,动态地正确转换
    整数
    值:

  • 临时表将在会话结束时自动删除。如果您在同一个会话中多次运行此操作,则只需截断现有的临时表,或者在每个事务之后删除它

    相关的:


    自Postgres 9.4以来,您现在可以使用强制空值。这将导致空字符串转换为空字符串。非常方便,尤其是CSV文件

    语法如下:使用(csv格式,分隔符“;”,FORCE_NULL(columnname)),将表从“/path/复制到/file.csv”


    文档中解释了进一步的详细信息:

    您是否可以尝试删除黑色斜杠,从而得到
    NULL'”
    ?请显示CSV文件中的一些实际行。NULL是由实际的空字符串(即nothing)表示还是由两个双引号表示?选项
    FORCE_NULL
    带有下划线,应该在“with(…)”子句中指定。例如:
    将表格从'/path/复制到/file.csv',格式为(csv,分隔符';',强制为空(field1,field2,field3))
    @spatar您是对的,这确实是当前首选的语法。即使在版本13中,我使用的语法仍然受支持,但使用“标准语法”更有意义。我已经改正了我的例子,谢谢!有没有一种方法可以告诉force_null所有字段,而不列出它们?类似于FORCE_NULL(*)的东西?@ZacharyRyanSmith这似乎只适用于FORCE_QUOTE,但您当然可以尝试看看它是否有效。起初我不相信选项2。然后,我看到是欧文
    String sql = "COPY " + tableName + " FROM STDIN (FORMAT csv,DELIMITER ',', NULL '\"\"'  HEADER true)";
    
    -- empty temp table with identical structure
    CREATE TEMP 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;