“@”的转义字符——JDBC?
Posted
技术标签:
【中文标题】“@”的转义字符——JDBC?【英文标题】:escape character for '@' -- JDBC? 【发布时间】:2018-11-05 01:49:45 【问题描述】:我正在批量插入 mysql 表:
insert into table1 (field1, field2) values("aa@gmail.com", "f2 value"), ("cc@gmail.com", "another f2 here");
给值字符串中的字符“@”错误:
com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: 你的 SQL 语法有错误;检查与您的 MySQL 服务器版本相对应的手册以获取正确的语法,以便在“插入买家(字段 1,字段 2)值(第 1 行的“aa@”)附近使用 在 sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) 在 sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62) 在 sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) 在 java.lang.reflect.Constructor.newInstance(Constructor.java:423) 在 com.mysql.jdbc.Util.handleNewInstance(Util.java:425) 在 com.mysql.jdbc.Util.getInstance(Util.java:408) 在 com.mysql.jdbc.SQLError.createSQLException(SQLError.java:943) 在 com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3970) 在 com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3906) 在 com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2524) 在 com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2677) 在 com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2549) 在 com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:1861) 在 com.mysql.jdbc.PreparedStatement.executeUpdateInternal(PreparedStatement.java:2073) 在 com.mysql.jdbc.PreparedStatement.executeUpdateInternal(PreparedStatement.java:2009) 在 com.mysql.jdbc.PreparedStatement.executeLargeUpdate(PreparedStatement.java:5098) 在 com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:1994)
我怎样才能解决这个问题 - JDBC 是否有某种转义字符可以解决这个问题?
注意:我知道 JDBC 批处理执行。我正在寻找上述解决方案 - 如果有的话:
pStat.addBatch();
pStat.executeBatch();
TIA。
进一步说明: 上面的插入查询直接在 MySQL 上运行良好,中间没有 JDBC。另请注意:当 JDBC 本身使用 pStat.getString("aa@gmail.com");
设置参数时,这不是问题——因此批处理 execn 是一种解决方案。
【问题讨论】:
是插入本身的错误吗?你试过括号吗? @DanielMarcus 请参阅“进一步说明”。谢谢你的评论。 感谢@xavierz,这使它成为 jdbc 问题而不是 sql 问题 用单引号代替双引号有帮助吗:values('aa@gmail.com', 'f2 value')
, ...?
@MarkusPscheidt no - 同样的错误。
【参考方案1】:
尝试使用 PreparedStatement。自动解析特殊字符,避免sql注入。
String queryStr = "insert into table1 (field1, field2) values(?, ?);"
try
PreparedStatement preparedStatement = conn.prepareStatement(queryStr);
preparedStatement.setString(1, "aa@gmail.com");
preparedStatement.setString(2, "f2 value");
preparedStatement.executeUpdate();
catch (SQLException e)
// Error
finally
if (preparedStatement != null)
preparedStatement.close();
if (conn != null)
conn.close();
更多示例:https://www.mkyong.com/jdbc/jdbc-preparestatement-example-insert-a-record/
【讨论】:
【参考方案2】:使用单引号:
insert into table1 (field1, field2)
values('aa@gmail.com', 'f2 value'), ('cc@gmail.com', 'another f2 here');
【讨论】:
SQL 的最佳实践是在字符串文字周围使用单引号,但如果ANSI_QUOTES
不包含在 sql_mode
中,MySQL 确实允许在字符串文字周围使用双引号。【参考方案3】:
我不认为错误消息表明“@”符号字符存在问题。
MySQL 语法错误“right syntax to use near”通常指向遇到问题的 first 标记。在这种情况下,MySQL 似乎反对INSERT
。
...在第 1 行的“
insert into buyers (field1, field2) values ('aa@
”附近
我怀疑在 SQL 文本中 insert
之前有一些东西,并且 MySQL 看到了多个语句。这只是一个猜测,我们没有看到实际的代码。
我建议在执行或准备之前显示 SQL 文本的实际内容。
【讨论】:
那么它为什么在 SQL 剪贴簿上运行良好。我正在将查询打印到控制台 - 复制/粘贴到剪贴簿以运行。 此外——该行并没有在“@”处结束。 @xavierz:我无法解释您所观察到的行为;我不可能重现这种行为。我的建议是,就 JDBC 和“@”字符而言,您正在寻找错误的树。使用不包含“@”字符的 field1 值进行测试应该相当简单。 @xavierz:我的怀疑是查询中有多个 SQL 语句。如果 SQL 文本是INSERT INTO sometable ( ... ) VALUES (...),(...); insert into buyers ...
,我们会预料到这种行为。 MySQL 会在第二次插入时标记错误,因为这是第二个 语句。一个查询中不允许运行多个 SQL 语句。 (同样,我只是猜测,因为没有显示代码。)
如果问题出在语句中的 @
符号字符上,我认为这不是 JDBC 问题。至少,我以前从未遇到过这个问题。我怀疑在字符串被传递给 JDBC 之前,是其他东西在修改字符串。(同样,没有看到正在执行的实际代码,我们只是在猜测。)【参考方案4】:
从 Java 运行时,对特殊字符使用 UTF-8 代码。 @
的 UTF-8 代码是 \u0040
:
insert into table1 (field1, field2) values("aa\u0040gmail.com", "f2 value"), ("cc\u0040gmail.com", "another f2 here");
【讨论】:
【参考方案5】:正在同时执行两个由;
分隔的查询。
都解决了。
@
没有错。
感谢富有洞察力的 cmets 和答案。
【讨论】:
以上是关于“@”的转义字符——JDBC?的主要内容,如果未能解决你的问题,请参考以下文章
通过 JTDS 驱动程序执行 SQL Server 调用时出现“第 24 行位置的 JDBC 转义语法无效 '=' 预期字符”错误的原因?
MyBatis踩坑之SQLProvider转义字符被删除问题