Bootstrap

expect DOT, actual DOT pos 27, line 2, column 13, token DOT;SQL state [null];

项目场景:

新增数据的一个接口,页面请求数据,保存数据在其他系统,还有请求日志保存操作。
数据库:sqlserver、mysql


问题描述

此bug刚开发现是偶发性,请求就报错,重启后这种情况就不存在了,等一段时间,又会出现。
后续通过测试稳定复现后发现,有一个参数(主键),同一个主键的情况下,第一次请求会报错,第二次请求就是不会报错。
看到sql报错后就一直围绕sqlserver sql 语法上进行排查问题,请教了大佬,也尝试了很多方法优化sql,排除关键字,都是无效。

报错sql: sql看起来也没什么问题

    SELECT top (1)
      tbdsl.FNAME AS fname ,
      t_bd_operatorentry.FNUMBER AS fnumber
    FROM
      T_BD_STAFF tbds
      LEFT JOIN T_BD_STAFF_L tbdsl ON tbds.FSTAFFID = tbdsl.FSTAFFID
      LEFT JOIN T_BD_OPERATORENTRY t_bd_operatorentry ON t_bd_operatorentry.FSTAFFID = tbds.FSTAFFID
    WHERE tbds.FNUMBER = #{staffId}

问题代码:这段代码看起来没什么错,转换保存数据用的


    @Override
    public void add(String bizType, String params, String result, String errorMessage) {
        this.save(crmToErpSysLog);
    }
    
    @Async("taskLogExecutor")
    @Override
    public void saveResult(String bizType, String param, String result) {
        add(bizType, JSONObject.toJSONString(param), resultCode, errorMsg);
    }

报错日志

Creating a new SqlSession
Creating a new SqlSession
SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@5dd014d2] was not registered for synchronization because synchronization is not active
SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@4d2d8d3b] was not registered for synchronization because synchronization is not active
JDBC Connection [com.alibaba.druid.proxy.jdbc.ConnectionProxyImpl@5a8e80c7] will not be managed by Spring
==>  Preparing: SELECT top (1) tbdsl.FNAME AS fname , t_bd_operatorentry.FNUMBER AS fnumber FROM T_BD_STAFF tbds LEFT JOIN T_BD_STAFF_L tbdsl ON tbds.FSTAFFID = tbdsl.FSTAFFID LEFT JOIN T_BD_OPERATORENTRY t_bd_operatorentry ON t_bd_operatorentry.FSTAFFID = tbds.FSTAFFID WHERE tbds.FNUMBER = ?
Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@5dd014d2]
JDBC Connection [com.alibaba.druid.proxy.jdbc.ConnectionProxyImpl@5a8e80c7] will not be managed by Spring
==>  Preparing: INSERT INTO crm_to_erp_sys_log ( biz_type, params, result, origin, destination, create_time, update_time ) VALUES ( ?, ?, ?, ?, ?, ?, ? )
==> Parameters: CONTRACT(String), "{\"ignoreInterationFlag\":\"\",\"interationFlags\":\"\",\"isAutoAdjustField\":\"false\",\"isAutoSubmitAndAudit\":\"true\",\"isDeleteEntry\":\"true\",\"isEntryBatchFill\":\"true\",\"isVerifyBaseDataField\":\"false\",\"model\":{\"fDataValue\":\"HT202208300111112\",\"fEntryID\":0,\"fId\":{\"fNumber\":\"keyanhetong\"},\"fNumber\":\"HT202208300111112\"},\"needReturnFields\":[],\"needUpDateFields\":[],\"numberSearch\":\"true\",\"subSystemId\":\"\",\"validateFlag\":\"true\"}"(String), 0(String), CRM(String), ERP(String), 2022-08-31T14:23:40.367008(LocalDateTime), 2022-08-31T14:23:40.367008(LocalDateTime)
<==    Updates: 1
Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@4d2d8d3b]
2022-08-31 14:23:40.618 ERROR 42168 --- [nio-8012-exec-1] c.n.c.d.advice.WebExceptionAdvice        : RuntimeException occurred

org.springframework.jdbc.UncategorizedSQLException: 
### Error querying database.  Cause: java.sql.SQLException: sql injection violation, syntax error: syntax error, error in :'     tbdsl.FNAME AS fname ,
      t', expect DOT, actual DOT pos 27, line 2, column 13, token DOT : SELECT top (1)
      tbdsl.FNAME AS fname ,
      t_bd_operatorentry.FNUMBER AS fnumber
    FROM
      T_BD_STAFF tbds
      LEFT JOIN T_BD_STAFF_L tbdsl ON tbds.FSTAFFID = tbdsl.FSTAFFID
      LEFT JOIN T_BD_OPERATORENTRY t_bd_operatorentry ON t_bd_operatorentry.FSTAFFID = tbds.FSTAFFID
    WHERE tbds.FNUMBER = ?
### The error may exist in file [D:\Project\dsc-data\nmdx-cloud-dataswitchcenter\target\classes\mapper\erp\ErpUserMapper.xml]
### The error may involve com.nmdx.cloud.dataswitchcenter.mapper.erp.ErpUserMapper.queryStaffSaleNumber
### The error occurred while executing a query
### SQL: SELECT top (1)       tbdsl.FNAME AS fname ,       t_bd_operatorentry.FNUMBER AS fnumber     FROM       T_BD_STAFF tbds       LEFT JOIN T_BD_STAFF_L tbdsl ON tbds.FSTAFFID = tbdsl.FSTAFFID       LEFT JOIN T_BD_OPERATORENTRY t_bd_operatorentry ON t_bd_operatorentry.FSTAFFID = tbds.FSTAFFID     WHERE tbds.FNUMBER = ?
### Cause: java.sql.SQLException: sql injection violation, syntax error: syntax error, error in :'     tbdsl.FNAME AS fname ,
      t', expect DOT, actual DOT pos 27, line 2, column 13, token DOT : SELECT top (1)
      tbdsl.FNAME AS fname ,
      t_bd_operatorentry.FNUMBER AS fnumber
    FROM
      T_BD_STAFF tbds
      LEFT JOIN T_BD_STAFF_L tbdsl ON tbds.FSTAFFID = tbdsl.FSTAFFID
      LEFT JOIN T_BD_OPERATORENTRY t_bd_operatorentry ON t_bd_operatorentry.FSTAFFID = tbds.FSTAFFID
    WHERE tbds.FNUMBER = ?
; uncategorized SQLException; SQL state [null]; error code [0]; sql injection violation, syntax error: syntax error, error in :'     tbdsl.FNAME AS fname ,
      t', expect DOT, actual DOT pos 27, line 2, column 13, token DOT : SELECT top (1)
      tbdsl.FNAME AS fname ,
      t_bd_operatorentry.FNUMBER AS fnumber
    FROM
      T_BD_STAFF tbds
      LEFT JOIN T_BD_STAFF_L tbdsl ON tbds.FSTAFFID = tbdsl.FSTAFFID
      LEFT JOIN T_BD_OPERATORENTRY t_bd_operatorentry ON t_bd_operatorentry.FSTAFFID = tbds.FSTAFFID
    WHERE tbds.FNUMBER = ?; nested exception is java.sql.SQLException: sql injection violation, syntax error: syntax error, error in :'     tbdsl.FNAME AS fname ,
      t', expect DOT, actual DOT pos 27, line 2, column 13, token DOT : SELECT top (1)
      tbdsl.FNAME AS fname ,
      t_bd_operatorentry.FNUMBER AS fnumber
    FROM
      T_BD_STAFF tbds
      LEFT JOIN T_BD_STAFF_L tbdsl ON tbds.FSTAFFID = tbdsl.FSTAFFID
      LEFT JOIN T_BD_OPERATORENTRY t_bd_operatorentry ON t_bd_operatorentry.FSTAFFID = tbds.FSTAFFID
    WHERE tbds.FNUMBER = ?
	at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:89) ~[spring-jdbc-5.2.1.RELEASE.jar:5.2.1.RELEASE]
	at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:81) ~[spring-jdbc-5.2.1.RELEASE.jar:5.2.1.RELEASE]
	at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:81) ~[spring-jdbc-5.2.1.RELEASE.jar:5.2.1.RELEASE]
	at org.mybatis.spring.MyBatisExceptionTranslator.translateExceptionIfPossible(MyBatisExceptionTranslator.java:88) ~[mybatis-spring-2.0.5.jar:2.0.5]
	at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:440) ~[mybatis-spring-2.0.5.jar:2.0.5]
	at com.sun.proxy.$Proxy196.selectOne(Unknown Source) ~[na:na]
	at org.mybatis.spring.SqlSessionTemplate.selectOne(SqlSessionTemplate.java:159) ~[mybatis-spring-2.0.5.jar:2.0.5]
	at com.baomidou.mybatisplus.core.override.MybatisMapperMethod.execute(MybatisMapperMethod.java:90) ~[mybatis-plus-core-3.4.1.jar:3.4.1]
	at com.baomidou.mybatisplus.core.override.MybatisMapperProxy$PlainMethodInvoker.invoke(MybatisMapperProxy.java:148) ~[mybatis-plus-core-3.4.1.jar:3.4.1]
	at com.baomidou.mybatisplus.core.override.MybatisMapperProxy.invoke(MybatisMapperProxy.java:89) ~[mybatis-plus-core-3.4.1.jar:3.4.1]
	at com.sun.proxy.$Proxy259.queryStaffSaleNumber(Unknown Source) ~[na:na]
	at com.nmdx.cloud.dataswitchcenter.service.impl.ErpUserServiceImpl.queryStaffSaleNumber(ErpUserServiceImpl.java:63) ~[classes/:na]
	at com.nmdx.cloud.dataswitchcenter.service.impl.ErpUserServiceImpl$$FastClassBySpringCGLIB$$59a4ce8.invoke(<generated>) ~[classes/:na]
	at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218) ~[spring-core-5.2.1.RELEASE.jar:5.2.1.RELEASE]
	at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:769) ~[spring-aop-5.2.1.RELEASE.jar:5.2.1.RELEASE]
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163) ~[spring-aop-5.2.1.RELEASE.jar:5.2.1.RELEASE]
	at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:747) ~[spring-aop-5.2.1.RELEASE.jar:5.2.1.RELEASE]
	at com.baomidou.dynamic.datasource.aop.DynamicDataSourceAnnotationInterceptor.invoke(DynamicDataSourceAnnotationInterceptor.java:49) ~[dynamic-datasource-spring-boot-starter-3.1.0.jar:3.1.0]
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.2.1.RELEASE.jar:5.2.1.RELEASE]
	at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:747) ~[spring-aop-5.2.1.RELEASE.jar:5.2.1.RELEASE]
	at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:689) ~[spring-aop-5.2.1.RELEASE.jar:5.2.1.RELEASE]
	at com.nmdx.cloud.dataswitchcenter.service.impl.ErpUserServiceImpl$$EnhancerBySpringCGLIB$$bd5b6f41.queryStaffSaleNumber(<generated>) ~[classes/:na]
	at com.nmdx.cloud.dataswitchcenter.foreign.erp.processor.ErpSaleOrderProcessor.buildSaveOrderEntity(ErpSaleOrderProcessor.java:303) ~[classes/:na]
	at com.nmdx.cloud.dataswitchcenter.foreign.erp.processor.ErpSaleOrderProcessor$$FastClassBySpringCGLIB$$63fe5959.invoke(<generated>) ~[classes/:na]
	at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218) ~[spring-core-5.2.1.RELEASE.jar:5.2.1.RELEASE]
	at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:769) ~[spring-aop-5.2.1.RELEASE.jar:5.2.1.RELEASE]
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163) ~[spring-aop-5.2.1.RELEASE.jar:5.2.1.RELEASE]
	at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:747) ~[spring-aop-5.2.1.RELEASE.jar:5.2.1.RELEASE]
	at com.baomidou.dynamic.datasource.aop.DynamicDataSourceAnnotationInterceptor.invoke(DynamicDataSourceAnnotationInterceptor.java:49) ~[dynamic-datasource-spring-boot-starter-3.1.0.jar:3.1.0]
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.2.1.RELEASE.jar:5.2.1.RELEASE]
	at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:747) ~[spring-aop-5.2.1.RELEASE.jar:5.2.1.RELEASE]
	at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:689) ~[spring-aop-5.2.1.RELEASE.jar:5.2.1.RELEASE]
	at com.nmdx.cloud.dataswitchcenter.foreign.erp.processor.ErpSaleOrderProcessor$$EnhancerBySpringCGLIB$$e9166334.buildSaveOrderEntity(<generated>) ~[classes/:na]
	at com.nmdx.cloud.dataswitchcenter.service.impl.ErpSaleOrderServiceImpl.addSaleOrder(ErpSaleOrderServiceImpl.java:78) ~[classes/:na]
	at com.nmdx.cloud.dataswitchcenter.service.impl.ErpSaleOrderServiceImpl$$FastClassBySpringCGLIB$$62df3830.invoke(<generated>) ~[classes/:na]
	at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218) ~[spring-core-5.2.1.RELEASE.jar:5.2.1.RELEASE]
	at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:769) ~[spring-aop-5.2.1.RELEASE.jar:5.2.1.RELEASE]
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163) ~[spring-aop-5.2.1.RELEASE.jar:5.2.1.RELEASE]
	at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:747) ~[spring-aop-5.2.1.RELEASE.jar:5.2.1.RELEASE]
	at com.baomidou.dynamic.datasource.aop.DynamicDataSourceAnnotationInterceptor.invoke(DynamicDataSourceAnnotationInterceptor.java:49) ~[dynamic-datasource-spring-boot-starter-3.1.0.jar:3.1.0]
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.2.1.RELEASE.jar:5.2.1.RELEASE]
	at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:747) ~[spring-aop-5.2.1.RELEASE.jar:5.2.1.RELEASE]
	at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:689) ~[spring-aop-5.2.1.RELEASE.jar:5.2.1.RELEASE]
	at com.nmdx.cloud.dataswitchcenter.service.impl.ErpSaleOrderServiceImpl$$EnhancerBySpringCGLIB$$89d37e19.addSaleOrder(<generated>) ~[classes/:na]
	at com.nmdx.cloud.dataswitchcenter.controller.ErpSaleOrderController.addSaleOrder(ErpSaleOrderController.java:40) ~[classes/:na]
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:na]
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
	at java.base/java.lang.reflect.Method.invoke(Method.java:566) ~[na:na]
	at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:190) ~[spring-web-5.2.1.RELEASE.jar:5.2.1.RELEASE]
	at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:138) ~[spring-web-5.2.1.RELEASE.jar:5.2.1.RELEASE]
	at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:106) ~[spring-webmvc-5.2.1.RELEASE.jar:5.2.1.RELEASE]
	at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:888) ~[spring-webmvc-5.2.1.RELEASE.jar:5.2.1.RELEASE]
	at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:793) ~[spring-webmvc-5.2.1.RELEASE.jar:5.2.1.RELEASE]
	at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) ~[spring-webmvc-5.2.1.RELEASE.jar:5.2.1.RELEASE]
	at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1040) ~[spring-webmvc-5.2.1.RELEASE.jar:5.2.1.RELEASE]
	at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:943) ~[spring-webmvc-5.2.1.RELEASE.jar:5.2.1.RELEASE]
	at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006) ~[spring-webmvc-5.2.1.RELEASE.jar:5.2.1.RELEASE]
	at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:909) ~[spring-webmvc-5.2.1.RELEASE.jar:5.2.1.RELEASE]
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:660) ~[tomcat-embed-core-9.0.27.jar:9.0.27]
	at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883) ~[spring-webmvc-5.2.1.RELEASE.jar:5.2.1.RELEASE]
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:741) ~[tomcat-embed-core-9.0.27.jar:9.0.27]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231) ~[tomcat-embed-core-9.0.27.jar:9.0.27]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.27.jar:9.0.27]
	at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53) ~[tomcat-embed-websocket-9.0.27.jar:9.0.27]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.27.jar:9.0.27]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.27.jar:9.0.27]
	at com.nmdx.cloud.dataswitchcenter.filter.RepeatableFilter.doFilter(RepeatableFilter.java:40) ~[classes/:na]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.27.jar:9.0.27]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.27.jar:9.0.27]
	at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100) ~[spring-web-5.2.1.RELEASE.jar:5.2.1.RELEASE]
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) ~[spring-web-5.2.1.RELEASE.jar:5.2.1.RELEASE]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.27.jar:9.0.27]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.27.jar:9.0.27]
	at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93) ~[spring-web-5.2.1.RELEASE.jar:5.2.1.RELEASE]
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) ~[spring-web-5.2.1.RELEASE.jar:5.2.1.RELEASE]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.27.jar:9.0.27]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.27.jar:9.0.27]
	at org.springframework.boot.actuate.metrics.web.servlet.WebMvcMetricsFilter.doFilterInternal(WebMvcMetricsFilter.java:108) ~[spring-boot-actuator-2.2.1.RELEASE.jar:2.2.1.RELEASE]
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) ~[spring-web-5.2.1.RELEASE.jar:5.2.1.RELEASE]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.27.jar:9.0.27]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.27.jar:9.0.27]
	at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201) ~[spring-web-5.2.1.RELEASE.jar:5.2.1.RELEASE]
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) ~[spring-web-5.2.1.RELEASE.jar:5.2.1.RELEASE]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.27.jar:9.0.27]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.27.jar:9.0.27]
	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:202) ~[tomcat-embed-core-9.0.27.jar:9.0.27]
	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96) ~[tomcat-embed-core-9.0.27.jar:9.0.27]
	at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:526) ~[tomcat-embed-core-9.0.27.jar:9.0.27]
	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:139) ~[tomcat-embed-core-9.0.27.jar:9.0.27]
	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92) ~[tomcat-embed-core-9.0.27.jar:9.0.27]
	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74) ~[tomcat-embed-core-9.0.27.jar:9.0.27]
	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343) ~[tomcat-embed-core-9.0.27.jar:9.0.27]
	at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:408) ~[tomcat-embed-core-9.0.27.jar:9.0.27]
	at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66) ~[tomcat-embed-core-9.0.27.jar:9.0.27]
	at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:861) ~[tomcat-embed-core-9.0.27.jar:9.0.27]
	at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1579) ~[tomcat-embed-core-9.0.27.jar:9.0.27]
	at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) ~[tomcat-embed-core-9.0.27.jar:9.0.27]
	at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128) ~[na:na]
	at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628) ~[na:na]
	at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) ~[tomcat-embed-core-9.0.27.jar:9.0.27]
	at java.base/java.lang.Thread.run(Thread.java:834) ~[na:na]
Caused by: java.sql.SQLException: sql injection violation, syntax error: syntax error, error in :'     tbdsl.FNAME AS fname ,
      t', expect DOT, actual DOT pos 27, line 2, column 13, token DOT : SELECT top (1)
      tbdsl.FNAME AS fname ,
      t_bd_operatorentry.FNUMBER AS fnumber
    FROM
      T_BD_STAFF tbds
      LEFT JOIN T_BD_STAFF_L tbdsl ON tbds.FSTAFFID = tbdsl.FSTAFFID
      LEFT JOIN T_BD_OPERATORENTRY t_bd_operatorentry ON t_bd_operatorentry.FSTAFFID = tbds.FSTAFFID
    WHERE tbds.FNUMBER = ?
	at com.alibaba.druid.wall.WallFilter.checkInternal(WallFilter.java:805) ~[druid-1.1.22.jar:1.1.22]
	at com.alibaba.druid.wall.WallFilter.connection_prepareStatement(WallFilter.java:258) ~[druid-1.1.22.jar:1.1.22]
	at com.alibaba.druid.filter.FilterChainImpl.connection_prepareStatement(FilterChainImpl.java:568) ~[druid-1.1.22.jar:1.1.22]
	at com.alibaba.druid.filter.FilterAdapter.connection_prepareStatement(FilterAdapter.java:930) ~[druid-1.1.22.jar:1.1.22]
	at com.alibaba.druid.filter.FilterEventAdapter.connection_prepareStatement(FilterEventAdapter.java:122) ~[druid-1.1.22.jar:1.1.22]
	at com.alibaba.druid.filter.FilterChainImpl.connection_prepareStatement(FilterChainImpl.java:568) ~[druid-1.1.22.jar:1.1.22]
	at com.alibaba.druid.proxy.jdbc.ConnectionProxyImpl.prepareStatement(ConnectionProxyImpl.java:341) ~[druid-1.1.22.jar:1.1.22]
	at com.alibaba.druid.pool.DruidPooledConnection.prepareStatement(DruidPooledConnection.java:350) ~[druid-1.1.22.jar:1.1.22]
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:na]
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
	at java.base/java.lang.reflect.Method.invoke(Method.java:566) ~[na:na]
	at org.apache.ibatis.logging.jdbc.ConnectionLogger.invoke(ConnectionLogger.java:55) ~[mybatis-3.5.6.jar:3.5.6]
	at com.sun.proxy.$Proxy400.prepareStatement(Unknown Source) ~[na:na]
	at org.apache.ibatis.executor.statement.PreparedStatementHandler.instantiateStatement(PreparedStatementHandler.java:86) ~[mybatis-3.5.6.jar:3.5.6]
	at org.apache.ibatis.executor.statement.BaseStatementHandler.prepare(BaseStatementHandler.java:88) ~[mybatis-3.5.6.jar:3.5.6]
	at org.apache.ibatis.executor.statement.RoutingStatementHandler.prepare(RoutingStatementHandler.java:59) ~[mybatis-3.5.6.jar:3.5.6]
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:na]
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
	at java.base/java.lang.reflect.Method.invoke(Method.java:566) ~[na:na]
	at org.apache.ibatis.plugin.Invocation.proceed(Invocation.java:49) ~[mybatis-3.5.6.jar:3.5.6]
	at com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor.intercept(MybatisPlusInterceptor.java:83) ~[mybatis-plus-extension-3.4.1.jar:3.4.1]
	at org.apache.ibatis.plugin.Plugin.invoke(Plugin.java:61) ~[mybatis-3.5.6.jar:3.5.6]
	at com.sun.proxy.$Proxy399.prepare(Unknown Source) ~[na:na]
	at com.baomidou.mybatisplus.core.executor.MybatisSimpleExecutor.prepareStatement(MybatisSimpleExecutor.java:94) ~[mybatis-plus-core-3.4.1.jar:3.4.1]
	at com.baomidou.mybatisplus.core.executor.MybatisSimpleExecutor.doQuery(MybatisSimpleExecutor.java:68) ~[mybatis-plus-core-3.4.1.jar:3.4.1]
	at org.apache.ibatis.executor.BaseExecutor.queryFromDatabase(BaseExecutor.java:325) ~[mybatis-3.5.6.jar:3.5.6]
	at org.apache.ibatis.executor.BaseExecutor.query(BaseExecutor.java:156) ~[mybatis-3.5.6.jar:3.5.6]
	at com.baomidou.mybatisplus.core.executor.MybatisCachingExecutor.query(MybatisCachingExecutor.java:165) ~[mybatis-plus-core-3.4.1.jar:3.4.1]
	at com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor.intercept(MybatisPlusInterceptor.java:65) ~[mybatis-plus-extension-3.4.1.jar:3.4.1]
	at org.apache.ibatis.plugin.Plugin.invoke(Plugin.java:61) ~[mybatis-3.5.6.jar:3.5.6]
	at com.sun.proxy.$Proxy398.query(Unknown Source) ~[na:na]
	at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:147) ~[mybatis-3.5.6.jar:3.5.6]
	at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:140) ~[mybatis-3.5.6.jar:3.5.6]
	at org.apache.ibatis.session.defaults.DefaultSqlSession.selectOne(DefaultSqlSession.java:76) ~[mybatis-3.5.6.jar:3.5.6]
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:na]
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
	at java.base/java.lang.reflect.Method.invoke(Method.java:566) ~[na:na]
	at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:426) ~[mybatis-spring-2.0.5.jar:2.0.5]
	... 97 common frames omitted
Caused by: com.alibaba.druid.sql.parser.ParserException: syntax error, error in :'     tbdsl.FNAME AS fname ,
      t', expect DOT, actual DOT pos 27, line 2, column 13, token DOT
	at com.alibaba.druid.sql.parser.SQLParser.printError(SQLParser.java:344) ~[druid-1.1.22.jar:1.1.22]
	at com.alibaba.druid.sql.parser.SQLStatementParser.parseStatementList(SQLStatementParser.java:532) ~[druid-1.1.22.jar:1.1.22]
	at com.alibaba.druid.sql.parser.SQLStatementParser.parseStatementList(SQLStatementParser.java:182) ~[druid-1.1.22.jar:1.1.22]
	at com.alibaba.druid.wall.WallProvider.checkInternal(WallProvider.java:624) ~[druid-1.1.22.jar:1.1.22]
	at com.alibaba.druid.wall.WallProvider.check(WallProvider.java:578) ~[druid-1.1.22.jar:1.1.22]
	at com.alibaba.druid.wall.WallFilter.checkInternal(WallFilter.java:792) ~[druid-1.1.22.jar:1.1.22]
	... 137 common frames omitted

2022-08-31 14:23:40.650  WARN 42168 --- [nio-8012-exec-1] .m.m.a.ExceptionHandlerExceptionResolver : Resolved [org.springframework.jdbc.UncategorizedSQLException: 
### Error querying database.  Cause: java.sql.SQLException: sql injection violation, syntax error: syntax error, error in :'     tbdsl.FNAME AS fname ,
      t', expect DOT, actual DOT pos 27, line 2, column 13, token DOT : SELECT top (1)
      tbdsl.FNAME AS fname ,
      t_bd_operatorentry.FNUMBER AS fnumber
    FROM
      T_BD_STAFF tbds
      LEFT JOIN T_BD_STAFF_L tbdsl ON tbds.FSTAFFID = tbdsl.FSTAFFID
      LEFT JOIN T_BD_OPERATORENTRY t_bd_operatorentry ON t_bd_operatorentry.FSTAFFID = tbds.FSTAFFID
    WHERE tbds.FNUMBER = ?
### The error may exist in file [D:\Project\dsc-data\nmdx-cloud-dataswitchcenter\target\classes\mapper\erp\ErpUserMapper.xml]
### The error may involve com.nmdx.cloud.dataswitchcenter.mapper.erp.ErpUserMapper.queryStaffSaleNumber
### The error occurred while executing a query
### SQL: SELECT top (1)       tbdsl.FNAME AS fname ,       t_bd_operatorentry.FNUMBER AS fnumber     FROM       T_BD_STAFF tbds       LEFT JOIN T_BD_STAFF_L tbdsl ON tbds.FSTAFFID = tbdsl.FSTAFFID       LEFT JOIN T_BD_OPERATORENTRY t_bd_operatorentry ON t_bd_operatorentry.FSTAFFID = tbds.FSTAFFID     WHERE tbds.FNUMBER = ?
### Cause: java.sql.SQLException: sql injection violation, syntax error: syntax error, error in :'     tbdsl.FNAME AS fname ,
      t', expect DOT, actual DOT pos 27, line 2, column 13, token DOT : SELECT top (1)
      tbdsl.FNAME AS fname ,
      t_bd_operatorentry.FNUMBER AS fnumber
    FROM
      T_BD_STAFF tbds
      LEFT JOIN T_BD_STAFF_L tbdsl ON tbds.FSTAFFID = tbdsl.FSTAFFID
      LEFT JOIN T_BD_OPERATORENTRY t_bd_operatorentry ON t_bd_operatorentry.FSTAFFID = tbds.FSTAFFID
    WHERE tbds.FNUMBER = ?
; uncategorized SQLException; SQL state [null]; error code [0]; sql injection violation, syntax error: syntax error, error in :'     tbdsl.FNAME AS fname ,
      t', expect DOT, actual DOT pos 27, line 2, column 13, token DOT : SELECT top (1)
      tbdsl.FNAME AS fname ,
      t_bd_operatorentry.FNUMBER AS fnumber
    FROM
      T_BD_STAFF tbds
      LEFT JOIN T_BD_STAFF_L tbdsl ON tbds.FSTAFFID = tbdsl.FSTAFFID
      LEFT JOIN T_BD_OPERATORENTRY t_bd_operatorentry ON t_bd_operatorentry.FSTAFFID = tbds.FSTAFFID
    WHERE tbds.FNUMBER = ?; nested exception is java.sql.SQLException: sql injection violation, syntax error: syntax error, error in :'     tbdsl.FNAME AS fname ,
      t', expect DOT, actual DOT pos 27, line 2, column 13, token DOT : SELECT top (1)
      tbdsl.FNAME AS fname ,
      t_bd_operatorentry.FNUMBER AS fnumber
    FROM
      T_BD_STAFF tbds
      LEFT JOIN T_BD_STAFF_L tbdsl ON tbds.FSTAFFID = tbdsl.FSTAFFID
      LEFT JOIN T_BD_OPERATORENTRY t_bd_operatorentry ON t_bd_operatorentry.FSTAFFID = tbds.FSTAFFID
    WHERE tbds.FNUMBER = ?]

原因分析:

经过测试定位问题点得知异常是在保存数据代码那段的 @Async 注解 ,猜测可能是 SpringBoot 的事务和异步机制导致sql注入问题,导致sql报错。


解决方案:

将@Async 注解放其他方法上

    @Async("taskLogExecutor")
    @Override
    public void add(String bizType, String params, String result, String errorMessage) {
        this.save(crmToErpSysLog);
    }
   
    @Override
    public void saveResult(String bizType, String param, String result) {
        add(bizType, JSONObject.toJSONString(param), resultCode, errorMsg);
    }
;