preparedStatement.setString(1,"null"),被解释为 null 而不是字符串(在preparedStatement.addBatch() 之后)

Posted

技术标签:

【中文标题】preparedStatement.setString(1,"null"),被解释为 null 而不是字符串(在preparedStatement.addBatch() 之后)【英文标题】:preparedStatement.setString(1,"null"), is being interpreted as null instead of a string (after preparedStatement.addBatch()) 【发布时间】:2019-04-18 10:24:09 【问题描述】:

PreparedStatement setString 采用“null”(就像 String a = "null"),在 .addBatch 之后它被转换为正常的 null(就像 String a = null 一样)。

我不知道如何能够绕过这种误解,因为很多行在全部添加为批处理之后会立即执行...(sql语句是INSERT INTO...)( VarChar 不能为空,但 String a = "null" 可以被表接受,如果它没有批量发送......整个程序由于来自服务器的错误消息而停止)

错误信息: 将数据写入数据库时​​出错... org.netezza.error.NzSQLException:错误:第 17 列:字段不能包含空值

代码:

preparedStatement.setString(17, x); //currently x was recieved as "null"
preparedStatement.addBatch() //after other parameters were filled then this statement
preparedStatement.executeBatch(); //after the logs this statement is executed.

希望有一个快速解决方案

我使用了这种绕过方法,但认为可能有更好的方法......(因为我无法更改数据库默认值或操作数据......)

if(helper.toLowerCase().equals("null"))
    helper = (helper.equals("null") ? "null ":"NULL ");

preparedStatement.setString(17, helper);

【问题讨论】:

【参考方案1】:

请记住,我从未使用过 Netezza,也无法尝试任何东西。这是在 IBM Netezza 的官方文档中找到的信息集合。

如果我没看错的话,有一个文本值“null”的显式转换以识别值的缺失......对于external table。原因很简单,外部表是一个平面文件,所以它可能将所有内容存储为没有分隔符的 TEXT,但文件大小有分隔。

Handle the absence of a value

在 SQL 中,如果列被声明为非空,则记录必须包含值。当记录不包含列的值时,该列被认为是空的。该系统提供了一种显式和隐式的方法来传达空值。 - 显式方法在字段中包含特定标记而不是值。 默认情况下,此标记是单词“null”(不区分大小写)您可以使用 nullValue 选项将此标记更改为任何其他 1 - 4 个字符的字母标记。您可以在具有相邻空格的非字符串字段中出现显式空标记之前或之后。为了让系统识别字符串字段中的显式空标记,该标记不能有前面或后面的相邻空格。显式空标记方法无法表达完全由空标记文本组成的字符串。

那么,我们可以在The NullValue option看到同样的想法

指定用于空值的字符串,最大为 4 字节的 UTF-8 字符串。默认为“NULL”。

您可以将此表的此选项替换为任何其他 String 但我相信这只会解决问题...

所以我的解决方案是将您的表格的NullValue 设置为" "(一个空格)并在您的项目中修剪每个值,您将永远无法拥有" ",因为它将被修剪为@987654328 @。

【讨论】:

我在 null 之后使用了一个空格来绕过这个问题(“null”/“NULL”)......我不知道它是 netezza 的限制......有没有更好的方法能解决这个问题吗? 我已经用NullValue 选项的信息编辑了这个。这可能就在桌子上,对我来说很难说.. @Xero,如果您能确认如何设置选项,我将不胜感激。这对于将来经过这里的人来说可能很有用;) 我无法更改 NullValue 的表示,因为它是一个巨大的数据库,因此必须包含在内......我将检查是否可以在不绕过我使用此代码进行的情况下解决此问题: if(helper.toLowerCase().equals("null")) helper = (helper.equals("null") ? "null":"NULL"); 最好的部分是如果不使用 addBatch 则字符串 null 被正确采用 XD【参考方案2】:

鉴于您的问题,我认为您正在尝试插入字符串 null,除非另有说明。 解决此问题的最简单方法是将列的默认值设置为字符串null,这样您就不必担心在代码中指定它可能会将其解释为空,也可能不将其解释为空。 即对列定义添加约束NOT NULL DEFAULT 'null'

【讨论】:

@AxelH 他并不是建议摆脱 NOT NULL 约束,而是建议将列定义更改为 NOT NULL DEFAULT 'null',以便如果从插入语句中省略列,它将具有单词"null" 默认在其中。对我来说似乎很合理。 @AlexH,在我的回答中,我提到了 adding DEFAULT 约束不删除它。 @JonK 不是那样读的!! "null" 已经是提供的值,所以它可能不起作用,但它可以! @AxelH 通过在preparedStatment 中使用“null”来克服问题 - 我们为什么不干脆不使用它,让数据库来处理它。 ;)

以上是关于preparedStatement.setString(1,"null"),被解释为 null 而不是字符串(在preparedStatement.addBatch() 之后)的主要内容,如果未能解决你的问题,请参考以下文章