Java PreparedStatement使用两个单引号作为空字符串参数

时间:2011-02-11 18:01:41

标签: java sql escaping prepared-statement

我正在使用PreparedStatement和sql,如:

String sql = "insert into foo (a,b,c) values (?,?,?)";
 ps = conn.prepareStatement(sql);

  ps.setString(psIndex++, a);
  ps.setString(psIndex++, b);
  ps.setString(psIndex++, c);

但是如果任何变量是空字符串,则结果语句将获得两个单引号。如:VALUES ('foo','','')然后我得到一个例外,因为两个单引号是一个转义序列。

我无法相信我通过搜索找不到任何东西,但我不能。这是怎么回事?

6 个答案:

答案 0 :(得分:3)

由于OP没有做@Adam在评论中建议的内容,我会这样做。它对未来的读者很有用。感谢@ user119179的想法。

它可能是我们正在使用的JDBC驱动程序中的错误。驱动程序的提供者应该知道''是一个转义序列。

实际上,更新驱动程序似乎解决了OP的错误。

答案 1 :(得分:2)

  

如:VALUES('foo','','')然后我得到一个例外,因为两个单引号是一个转义序列。

这里有一个误解。两个单引号空字符串。没有逃脱序列发生。只有当它在另一个单引号中时,它才是一个转义报价。如果您收到异常,则可能是其他地方,例如数据库中列的约束。

声明

insert into foo (a,b,c) values ('foo','','')

是非常有效的SQL。

答案 2 :(得分:0)

@cyberkiwi是对的。可能是您的列不接受空值。你有什么例外?如果您有任何日志报告,请分享。

答案 3 :(得分:0)

将单引号'替换为UNICODE \u2019值。 有关详细信息,请单击此url

答案 4 :(得分:0)

您还没有共享Java异常,这将有助于您给出准确的答案。

程序中有两个方面-Java和DB约束。

对于Java,空字符串为""(它的双引号而不是单引号),只要您的Java引用-abc都具有此值当value为空时,就PreparedStatement而言,我看不到任何问题。如果使用PreparedStatement,则不必担心单引号转义序列。我不确定为什么您将值列出为['foo','',''],它应该是["foo","",""]

第二个方面,由于约束,您的数据库列abc可能不允许空值完全是另一回事,并且无法用Java代码进行控制。在这种情况下,需要更改数据库表模式以允许使用默认值。

当有人通过直接在查询字符串(例如"insert into foo (a,b,c) values ('foo','','')";或带有WHERE的{​​{1}}子句中附加值来准备SQL查询时,有关单引号转义序列的讨论很重要。尽管由于SQL注入漏洞,但不建议使用此方法。

答案 5 :(得分:-2)

编辑:正如其他人所指出的,你不应该做任何特别的事情来将空字符串传递给参数化查询。

但是,以防万一,如果您碰巧在查询中使用动态SQL:

Declare sqlText VARCHAR(MAX)
set sqlText = 'SELECT ....'
EXEC(sqlText)

然后你需要将每个单引号转义为''''以获得等效于空字符串的内容。所以,共有4个引号。前两个单引号相当于在运行时获取单引号。另外两个单引号将在运行时获得结束报价。