'@'的转义字符 - JDBC?

时间:2018-05-25 15:55:54

标签: java mysql sql jdbc

我正在批量插入MySQL表:

insert into table1 (field1, field2) values("aa@gmail.com", "f2 value"), ("cc@gmail.com", "another f2 here");

在值String:

中为字符'@'提供错误
  

com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException:您的SQL语法中有错误;检查与您的MySQL服务器版本对应的手册,以便在'insert into buyer(field1,field2)值附近使用正确的语法('aa @'在第1行       at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)       at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)       at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)       at 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)       at 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。

进一步说明:上面的插入查询可以在没有JDBC的MySQL之间直接运行。另请注意:当JDBC本身使用pStat.getString("aa@gmail.com");设置参数时,这不是问题 - 因此批处理execn是一种解决方案。

5 个答案:

答案 0 :(得分:3)

尝试使用PreparedStatement。它会自动解析特殊字符并避免sql注入。

d = {'A': [{'B': [{'C': [{'D1':[]}, {'D2': []}]}]}]} # just an example
def walk(_d, path):
   a, *b = path
   if isinstance(_d, list):
     _d = [i for i in _d if a in i]
     if not _d:
       return None
     _d = _d[0]
   return _d[a] if not b else walk(_d[a], b)

tests = [[['A','B','C','D1'], []], [['A','B','C','D2'], []], [['A','B','C','D3'], None]]
for a, b in tests:
  assert walk(d, a) == b

print('all cases passed')

更多示例:https://www.mkyong.com/jdbc/jdbc-preparestatement-example-insert-a-record/

答案 1 :(得分:1)

我不认为错误消息表明' @'在标志字符。

MySQL语法错误"正确的语法在"附近使用通常指向遇到问题的第一个标记。在这种情况下,看起来MySQL反对INSERT

  

...附近' insert into buyers (field1, field2) values ('aa@'在第1行

我怀疑在SQL文本中insert之前有一些东西,并且MySQL看到了多个语句。这只是一个猜测,我们没有看到实际的代码。

我建议在执行或准备之前显示SQL文本的实际内容。

答案 2 :(得分:0)

使用单引号:

insert into table1 (field1, field2) 
  values('aa@gmail.com', 'f2 value'), ('cc@gmail.com', 'another f2 here');

答案 3 :(得分:0)

从Java运行时,使用UTF-8代码表示特殊字符。 @的UTF-8代码为\u0040

insert into table1 (field1, field2) values("aa\u0040gmail.com", "f2 value"), ("cc\u0040gmail.com", "another f2 here");

答案 4 :(得分:0)

在一个中用;分隔两个查询。 全部解决了。 @没有错。

感谢您提供富有洞察力的评论和答案。