“@”的转义字符——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?的主要内容,如果未能解决你的问题,请参考以下文章

如何转义mysql jdbc连接字符串中的特殊字符

通过 JTDS 驱动程序执行 SQL Server 调用时出现“第 24 行位置的 JDBC 转义语法无效 '=' 预期字符”错误的原因?

MyBatis踩坑之SQLProvider转义字符被删除问题

在没有 PreparedStatement 的情况下如何正确转义字符串?

转义字符有都哪些?

Java转义字符怎么输出的