我正在使用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','','')
然后我得到一个例外,因为两个单引号是一个转义序列。
我无法相信我通过搜索找不到任何东西,但我不能。这是怎么回事?
答案 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引用-a
,b
和c
都具有此值当value为空时,就PreparedStatement
而言,我看不到任何问题。如果使用PreparedStatement
,则不必担心单引号转义序列。我不确定为什么您将值列出为['foo','','']
,它应该是["foo","",""]
。
第二个方面,由于约束,您的数据库列a
,b
和c
可能不允许空值完全是另一回事,并且无法用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个引号。前两个单引号相当于在运行时获取单引号。另外两个单引号将在运行时获得结束报价。