Invalid SQL statement or JDBC escape, terminating ''' not found.的解决办法。

简介:

项目中一直报如下的错误:

项目架构如下:Struts2.2.3 +Hibernate3.3 +Spirng 3.0 +Log4J-1.2.16+jtds-1.2.5.

 
  1. log4j:ERROR Failed to excute sql  
  2. java.sql.SQLException: Invalid SQL statement or JDBC escape, terminating ''' not found.  
  3.     at net.sourceforge.jtds.jdbc.SQLParser.parse(SQLParser.java:1155)  
  4.     at net.sourceforge.jtds.jdbc.SQLParser.parse(SQLParser.java:156)  
  5.     at net.sourceforge.jtds.jdbc.JtdsStatement.executeImpl(JtdsStatement.java:684)  
  6.     at net.sourceforge.jtds.jdbc.JtdsStatement.executeUpdate(JtdsStatement.java:1166)  
  7.     at net.sourceforge.jtds.jdbc.JtdsStatement.executeUpdate(JtdsStatement.java:1119)  
  8.     at org.apache.log4j.jdbc.JDBCAppender.execute(JDBCAppender.java:178)  
  9.     at org.apache.log4j.jdbc.JDBCAppender.flushBuffer(JDBCAppender.java:250)  
  10.     at org.apache.log4j.jdbc.JDBCAppender.append(JDBCAppender.java:146)  
  11.     at org.apache.log4j.AppenderSkeleton.doAppend(AppenderSkeleton.java:251)  
  12.     at org.apache.log4j.helpers.AppenderAttachableImpl.appendLoopOnAppenders(AppenderAttachableImpl.java:66)  
  13.     at org.apache.log4j.Category.callAppenders(Category.java:206)  
  14.     at org.apache.log4j.Category.forcedLog(Category.java:391)  
  15.     at org.apache.log4j.Category.log(Category.java:856)  
  16.     at org.apache.commons.logging.impl.Log4JLogger.warn(Log4JLogger.java:222)  
  17.     at com.opensymphony.xwork2.util.logging.commons.CommonsLogger.warn(CommonsLogger.java:56)  
  18.     at org.apache.struts2.components.ServletUrlRenderer.renderFormUrl(ServletUrlRenderer.java:186)  
  19.     at org.apache.struts2.components.Form.populateComponentHtmlId(Form.java:220)  
  20.     at org.apache.struts2.components.UIBean.evaluateParams(UIBean.java:784)  
  21.     at org.apache.struts2.components.ClosingUIBean.start(ClosingUIBean.java:57)  
  22.     at org.apache.struts2.views.jsp.ComponentTagSupport.doStartTag(ComponentTagSupport.java:53)  
  23.     at org.apache.jsp.web.enterprise.add_jsp._jspx_meth_s_005fform_005f0(add_jsp.java:188)  
  24.     at org.apache.jsp.web.enterprise.add_jsp._jspx_meth_c_005fif_005f0(add_jsp.java:154)  
  25.     at org.apache.jsp.web.enterprise.add_jsp._jspService(add_jsp.java:115)  
  26.     at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)  
  27.     at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)  
  28.     at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:377)  
  29.     at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:313)  
  30.     at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:260)  
  31.     at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)  
  32.     at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)  
  33.     at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)  
  34.     at org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter.doFilter(StrutsPrepareAndExecuteFilter.java:88)  
  35.     at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)  
  36.     at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)  
  37.     at com.yaxing.util.ResFilter.doFilter(ResFilter.java:63)  
  38.     at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)  
  39.     at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)  
  40.     at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)  
  41.     at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)  
  42.     at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)  
  43.     at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)  
  44.     at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)  
  45.     at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:298)  
  46.     at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:857)  
  47.     at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:588)  
  48.     at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:489)  
  49.     at java.lang.Thread.run(Thread.java:619)  
  50.  
  51.  
  52.  

此错误表现为:执行查询语句没问题,但是执行插入的页面就都有问题,都报这错。很诡异的是,只打开这个页面就报错,而不管你执行了添加这个操作了没有,而且只报一次这个错,要想再见到这个错误,只有Redeploy了。。。。

虽然有这个错误,但是也不影响程序的执行。但是,咱是见不得项目中有些许的报错啊,心烦。

网上查了很多,

网上有人说是SQL语句的问题,一开始,也猜测是这种问题。但是检查了下SQL语句,发现并不是这个问题。

后来就怀疑是不是页面的问题,因为我打开这个添加的页面就报错,仔细一分析,排除了这种可能性!

再看看错误提示:log4j:ERROR Failed to excute sql

于是,八成是log4j的报错了。

log4j的配置文件如下:

 
  1. log4j.rootLogger=warn,db  
  2. log4j.appender.db=org.apache.log4j.jdbc.JDBCAppender  
  3. log4j.appender.db.BufferSize=1 
  4. log4j.appender.db.URL=jdbc\:jtds\:sqlserver\://server\:1434/pcbsyn  
  5. log4j.appender.db.driver=net.sourceforge.jtds.jdbc.Driver  
  6. log4j.appender.db.user=sa 
  7. log4j.appender.db.password=711 
  8. log4j.appender.db.sql=insert into logInfo(userId,userName,lclass,lmethod,lTime,llevel,message) values ('%X{userId}','%X{userName}','%C','%M','%d{yyyy-MM-dd HH\:mm\:ss}','%p','%m')  
  9. log4j.appender.db.layout=org.apache.log4j.PatternLayout  
  10.  
  11.  
  12.  

于是,把log4j从项目中去掉!再发布运行,果然就没有报错了。

这配置文件中涉及到SQL语句的部分也只有第8行:

 

 
  1. log4j.appender.DATABASE.sql=insert into logInfo(userId,userName,lclass,lmethod,lTime,llevel,message)values('%X{userId}','%X{userName}','%C','%M','%d{yyyy-MM-dd HH:mm:ss}','%p','%m') 

也只有这个里面出现了 单引号 " ' ".

 

 
  1. org.apache.log4j.jdbc.JDBCAppender 

从Apache网站上找到了下面的解释:

http://logging.apache.org/log4j/1.2/apidocs/org/apache/log4j/jdbc/JDBCAppender.html

The JDBCAppender provides for sending log events to a database.

WARNING: This version of JDBCAppender is very likely to be completely replaced in the future. Moreoever, it does not log exceptions.

Each append call adds to an ArrayList buffer. When the buffer is filled each log event is placed in a sql statement (configurable) and executed. BufferSizedb URLUser, & Password are configurable options in the standard log4j ways.

The setSql(String sql) sets the SQL statement to be used for logging -- this statement is sent to a PatternLayout (either created automaticly by the appender or added by the user). Therefore by default all the conversion patterns in PatternLayout can be used inside of the statement. (see the test cases for examples)

Overriding the getLogStatement(org.apache.log4j.spi.LoggingEvent) method allows more explicit control of the statement used for logging.

参见http://logging.apache.org/log4j/1.2/apidocs/org/apache/log4j/jdbc/JDBCAppender.html

查看JDBCAppender.java的源代码如下:

 

 
  1. /**  
  2.    * loops through the buffer of LoggingEvents, gets a  
  3.    * sql string from getLogStatement() and sends it to execute().  
  4.    * Errors are sent to the errorHandler.  
  5.    *  
  6.    * If a statement fails the LoggingEvent stays in the buffer!  
  7.    */ 
  8.   public void flushBuffer() {  
  9.     //Do the actual logging  
  10.     removes.ensureCapacity(buffer.size());  
  11.     for (Iterator i = buffer.iterator(); i.hasNext();) {  
  12.       try {  
  13.         LoggingEvent logEvent = (LoggingEvent)i.next();  
  14.         String sql = getLogStatement(logEvent);  
  15.         execute(sql);  
  16.         removes.add(logEvent);  
  17.       }  
  18.       catch (SQLException e) {  
  19.         errorHandler.error("Failed to excute sql", e, //此处报错 
  20.                ErrorCode.FLUSH_FAILURE);  
  21.       }  
  22.     } 

由此找到了报错的来源:程序第19行报错!这个方法的介绍,可以查看上面的注释部分。

重写JDBCAppender:

MyJDBCAppender.java 继承

getLogStatement()这个方法即可!具体的可以查看 org.apache.log4j.jdbc.JDBCAppender.java这个类的源代码!

 
  1. package com.yaxing.util;  
  2.  
  3. import org.apache.log4j.Category;  
  4. import org.apache.log4j.Logger;  
  5. import org.apache.log4j.Priority;  
  6. import org.apache.log4j.jdbc.JDBCAppender;  
  7. import org.apache.log4j.spi.LoggingEvent;  
  8.  
  9. public class MyJDBCAppender extends JDBCAppender {  
  10.     @Override 
  11.     protected String getLogStatement(LoggingEvent event) {  
  12.         String fqnOfCategoryClass = event.fqnOfCategoryClass;  
  13.         Category logger = Logger.getRootLogger();  
  14.         Priority level = event.getLevel();  
  15.         Object message = event.getMessage();  
  16.         Throwable throwable = null;  
  17.         LoggingEventUtil bEvent = new LoggingEventUtil(fqnOfCategoryClass, logger,  
  18.                 level, message, throwable);  
  19.         return super.getLogStatement(bEvent);  
  20.     }  


LoggingEventUtil.java继承 LoggingEvent :
 

覆盖里面的

 

 

 
  1. @Override 
  2. public String getThreadName() {  
  3.     String thrdName = super.getThreadName();  
  4.     if (thrdName.indexOf("'") != -1) {  
  5.         thrdName = thrdName.replaceAll("'""''");  
  6.     }  
  7.     return thrdName;  

即可!
 

 
  1. package com.yaxing.util;  
  2.  
  3. import org.apache.log4j.Category;  
  4. import org.apache.log4j.Priority;  
  5. import org.apache.log4j.spi.LoggingEvent;  
  6.  
  7. public class LoggingEventUtil extends LoggingEvent {  
  8.     private static final long serialVersionUID = 3359112146209080210L;  
  9.  
  10.     public LoggingEventUtil(String fqnOfCategoryClass, Category logger,  
  11.             Priority level, Object message, Throwable throwable) {  
  12.         super(fqnOfCategoryClass, logger, level, message, throwable);  
  13.     }  
  14.  
  15.     @Override 
  16.     public String getThreadName() {  
  17.         String thrdName = super.getThreadName();  
  18.         if (thrdName.indexOf("'") != -1) {  
  19.             thrdName = thrdName.replaceAll("'""''");  
  20.         }  
  21.         return thrdName;  
  22.     }  
  23.  
  24.     /**  
  25.      *   
  26.      *   
  27.      * @see org.apache.log4j.spi.LoggingEvent#getRenderedMessage()  
  28.      */ 
  29.     @Override 
  30.     public String getRenderedMessage() {  
  31.         String renderedMessage = super.getRenderedMessage();  
  32.  
  33.         if (renderedMessage != null && renderedMessage.indexOf("'") != -1)  
  34.             renderedMessage = renderedMessage.replaceAll("'""''");  
  35.         return renderedMessage;  
  36.     }  

最后在log4j.properties里面使用我们自定义的JDBCAppender-->MyJDBCAppender

到此,大功告成!

 


 本文转自 w156445045 51CTO博客,原文链接:http://blog.51cto.com/enetq/764054,如需转载请自行联系原作者


相关文章
|
3月前
|
SQL Java 数据库连接
[SQL]SQL注入与SQL执行过程(基于JDBC)
[SQL]SQL注入与SQL执行过程(基于JDBC)
52 0
|
7月前
|
SQL Java 数据库连接
JSP商品进出库管理系统myeclipse开发sql数据库bs框架java编程jdbc
JSP 商品进出库管理系统是一套完善的web设计系统,对理解JSP java编程开发语言有帮助,系统具有完整的源代码和数据库,开发环境为TOMCAT7.0,Myeclipse8.5开发,数据库为SQLSERVER2008,使用java语言开发,系统主要采用B/S模式开发。
54 0
|
7月前
|
SQL Java 数据库连接
JSP婚纱影楼管理系统myeclipse开发sql数据库bs框架java编程jdbc
JSP 婚纱影楼管理系统是一套完善的web设计系统,对理解JSP java编程开发语言有帮助,系统具有完整的源代码和数据库,开发环境为TOMCAT7.0,Myeclipse8.5开发,数据库为SQLSERVER2008,使用java语言开发,系统主要采用B/S模式开发。
51 0
|
7月前
|
SQL 存储 Java
JDBC Statement:执行 SQL 语句的重要接口
在Java应用程序中,与数据库进行交互是一项常见的任务。为了执行数据库操作,我们需要使用JDBC(Java Database Connectivity)来建立与数据库的连接并执行SQL语句。Statement接口是JDBC中的一个重要接口,它用于执行SQL语句并与数据库进行交互。本文将详细介绍Statement接口的使用,包括如何创建Statement对象、执行SQL语句、处理结果等内容。
108 0
|
11天前
|
SQL
SQL Server2008 安装报错Restart computer failed的解决办法
SQL Server2008 安装报错Restart computer failed的解决办法
11 0
|
7月前
|
SQL Java 数据库连接
JSP网上相亲交友系统myeclipse开发sql数据库bs框架java编程jdbc
JSP 网上相亲交友系统是一套完善的web设计系统,对理解JSP java编程开发语言有帮助,系统具有完整的源代码和数据库,开发环境为TOMCAT7.0,Myeclipse8.5开发,数据库为sqlserver2008,使用java语言开发,系统主要采用B/S模式开发。
70 0
|
4月前
|
SQL Java 关系型数据库
JDBC技术【SQL注入、JDBC批量添加数据、JDBC事务处理、其他查询方式】(三)-全面详解(学习总结---从入门到深化)
JDBC技术【SQL注入、JDBC批量添加数据、JDBC事务处理、其他查询方式】(三)-全面详解(学习总结---从入门到深化)
33 0
|
7月前
|
SQL Java 数据库连接
JSP大学生家教信息服务系统myeclipse开发sql数据库bs框架java编程jdbc
JSP 大学生家教信息服务系统是一套完善的web设计系统,对理解JSP java编程开发语言有帮助,系统具有完整的源代码和数据库,开发环境为TOMCAT7.0,Myeclipse8.5开发,数据库为SQLSERVER2008,使用java语言开发,系统主要采用B/S模式开发。
63 0
|
9月前
|
SQL Java 数据库连接
Java JDBC中的批处理SQL语句的详解
Java JDBC中的批处理SQL语句的详解
85 0
|
10月前
|
SQL 安全 数据库
SQL Server附加数据库的方法,及出现错误的解决办法(错误:5123)
SQL Server附加数据库的方法,及出现错误的解决办法(错误:5123)