1. 复现错误
今天在调试低代码的接口,突然报出如下的错误:
即You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'desc,name,is_deleted ) VALUES('测试哈','测试哈','测试项目',1 )' at line 11
。
于是,查看控制台报出的详细错误信息,如下图所示:
java.sql.SQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'desc,name,is_deleted ) VALUES('测试哈','测试哈','测试项目',1 )' at line 1
at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:120)
at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:122)
at com.mysql.cj.jdbc.ClientPreparedStatement.executeInternal(ClientPreparedStatement.java:953)
at com.mysql.cj.jdbc.ClientPreparedStatement.executeUpdateInternal(ClientPreparedStatement.java:1092)
at com.mysql.cj.jdbc.ClientPreparedStatement.executeUpdateInternal(ClientPreparedStatement.java:1040)
at com.mysql.cj.jdbc.ClientPreparedStatement.executeLargeUpdate(ClientPreparedStatement.java:1348)
at com.mysql.cj.jdbc.ClientPreparedStatement.executeUpdate(ClientPreparedStatement.java:1025)
at com.alibaba.druid.pool.DruidPooledPreparedStatement.executeUpdate(DruidPooledPreparedStatement.java:241)
at com.test.AppModelPageService.addData(AppModelPageService.java:904)
at com.test.AppModelPageService$$FastClassBySpringCGLIB$$81597048.invoke(<generated>)
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:688)
at com.test.AppModelPageService$$EnhancerBySpringCGLIB$$40f27572.addData(<generated>)
at com.sugon.cloud.lowcode.controller.AppModelPageController.AddData(AppModelPageController.java:125)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:197)
......
2. 分析错误
由java.sql.SQLSyntaxErrorException
可知,这是SQL
报出的语法错误。
找到打印的SQL
日志,如下图所示:
将红框中的MySQL
语句,复制到MySQL
控制台中执行,如下图所示:
我很确定insert into project(remark,desc,name,is_deleted ) VALUES('测试哈','测试哈','测试项目',1 );
,该MySQL
语句没有语法错误。
那只能考虑该语句中,是不是存在与MySQL关键字
冲突的字段了。
仔细一看,desc
正是MySQL
的关键字,表示降序排列,如下代码所示:
select * from product order by price desc;
3. 解决错误
由上分析可知,我的SQL语句insert into project(remark,desc,name,is_deleted ) VALUES('测试哈','测试哈','测试项目',1 );
中的desc
,与MySQL
中的desc
关键字发生了冲突。
因而,我可以有如下两种方法修改:
- 方法一
将我的desc
字段修改成其他不与MySQL
关键字冲突的字段,比如note
等。
- 方法二
在上述MySQL
语句中的desc
上添加反单引号(`),如下代码所示:
mysql> insert into project(remark,`desc`,name,is_deleted ) VALUES('测试哈','测试哈','测试项目',1 );
Query OK, 1 row affected (0.01 sec)
因而,我们在实际开发中,最好将添加、修改、查询等字段,都加上反单引号(`)。
避免与MySQL
的关键字发生冲突,从而减少不必要的麻烦。
4. 解决该错误的其他方法
我的错误是因为在insert
语句中,出现了与MySQL
关键字冲突的字段,在该冲突的字段上加上反单引号,即可解决问题。
如果你的错误不是该原因造成的,可以参考如下解决方法。
- 单引号、反单引号分不清
java
中键值用单引号(’),列名反单引号(`),比如
ed.insertData("insert into information(`nowtime`,`data`) values(current_time,'A');");
insertData
就是负责执行这句SQL
语句的,他最后返回受影响的条数,这个不用管。
其中:
-
列名分别是
nowtime
和data
(这里用反单引号) -
写入数据库的值是
current_time
和字符A
(这里用单引号)。
- 检查是否真为语法错误
这个一般都能看出来。
- 检查语句是否忘记空格
如下这个报错:
int result = ed.insertData("insert "+"into test"
+ "values(1) ");
把代码合成一句话执行,就没问题,如下所示:
int result = ed.insertData("insert into test values(1) ");
第一句话的test
和后面的values
之间没有空格,自然会报错。
读者要注意下你们是不是也是忘记了空格,这个错误经常发生在换行的时候。
因而,短小的SQL
语句还是写成一句话比较好,减少bug
产生效率。