`
gufenglian
  • 浏览: 50482 次
  • 性别: Icon_minigender_2
  • 来自: 深圳
社区版块
存档分类
最新评论

关于模糊查询和预编译一个很容易出错的地方

阅读更多

前两天,上面叫我改一下一个查询的sql语句,改成模糊查询。觉得这个非常简单,于是在mysql中查询之后,看到数据正常,就直接写到代码里面去了,没有测试直接交了上去。今天部门老大突然给我发了一个异常过来,刚刚开始怀疑部门老大发错地方了,结果才发现原来就是自己错了。感觉很没面子,这么点小东西都没做好,刚刚开始还不知道问题出在哪里,怎么看都像是对的,在网上查阅之后发现真的很容易出错,所以贴出来,希望以后不要遇到同样的事情,然后不管多简单的东西,记得测试之后再交上去。

 

 

在mysql中的测试语句:select serviceCode from smsconfiginfo where configName like '%aa%'

这样肯定是没问题的。

用预编译PreparedStatement,直接把语句改成了

stmt = con.prepareStatement(select serviceCode from smsconfiginfo where configName like '%?%')

然后stmt.setString(1,serviceNameKeyword);

是否貌似没什么问题。

 

当查询的时候发现抛这样一个异常:

  java.sql.SQLException: No parameters defined during prepareCall()
        at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:910)
        at com.mysql.jdbc.ServerPreparedStatement.getBinding(ServerPreparedStatement.java:751)
        at com.mysql.jdbc.ServerPreparedStatement.setString(ServerPreparedStatement.java:1857)
        at org.apache.commons.dbcp.DelegatingPreparedStatement.setString(DelegatingPreparedStatement.java:131)
        at org.apache.jsp.stat.statSmsMainProcessInclude_jsp._jspService(statSmsMainProcessInclude_jsp.java:195)
        at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:97)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:802)
        at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:332)
        at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:314)
        at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:264)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:802)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:252)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173)
        at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:672)
        at org.apache.catalina.core.ApplicationDispatcher.doInclude(ApplicationDispatcher.java:574)
        at org.apache.catalina.core.ApplicationDispatcher.include(ApplicationDispatcher.java:499)
        at org.apache.jasper.runtime.JspRuntimeLibrary.include(JspRuntimeLibrary.java:966)
        at org.apache.jsp.stat.smsYuanjing_jsp._jspService(smsYuanjing_jsp.java:59)
        at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:97)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:802)
        at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:332)
        at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:314)
        at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:264)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:802)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:252)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173)
        at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:213)
        at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:178)
        at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:126)
        at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:105)
        at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:541)
        at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:107)
        at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:148)
        at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:869)
        at org.apache.coyote.http11.Http11BaseProtocol$Http11ConnectionHandler.processConnection(Http11BaseProtocol.java:664)
        at org.apache.tomcat.util.net.PoolTcpEndpoint.processSocket(PoolTcpEndpoint.java:527)
        at org.apache.tomcat.util.net.LeaderFollowerWorkerThread.runIt(LeaderFollowerWorkerThread.java:80)
        at org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.java:684)
        at java.lang.Thread.run(Thread.java:595)

 

 

刚刚开始找到问题的根源,只知道自己只改了那一点代码于是先把

stmt = con.prepareStatement(select serviceCode from smsconfiginfo where configName like '%?%')

这个改为

stmt = con.prepareStatement(select serviceCode from smsconfiginfo where configName like '%aa%')

屏蔽掉设置参数,发现异常没有了

问题肯定就出在这个问号上,但是想象设置参数不就是用问号吗

仔细观察,发现这里把问号当成了条件,而不是参数的设置

这样

stmt = con.prepareStatement(select serviceCode from smsconfiginfo where configName like '%'?'%')

就可以了。

 

别小看字符串的问题,越容易的东西越容易出错。

分享到:
评论
9 楼 huanghuangjava 2016-08-13  
'%'?'%'
我的这样写查询不到结果
'%' ? '%'把?两边加上空格就正常了
8 楼 colinzhy 2012-05-14  
我的也查不出东西,不过'%'?'%'改成'%'||?||'%'之后就行了
7 楼 BelieveTheGod 2010-01-15  
虚心学习 , 我也遇到这问题了 谢谢 大家
6 楼 hilor 2009-12-31  
gufenglian 写道
liweixw 写道
stmt = con.prepareStatement(select serviceCode from smsconfiginfo where configName like '%?%')

改成
stmt = con.prepareStatement(select serviceCode from smsconfiginfo where configName like ?)
stmt.setString(1,"%"+serviceNameKeyword+"%");

这样不优雅点。  呵呵。。

理解下预编译语句区别就知道你犯这错误的原因了、。



呵呵,谢谢了,有时就是脑子转不过弯,谢谢分享。

建议把博客原文的写法改下,最好把你自己的代码也改成这样的. stmt = con.prepareStatement(select serviceCode from smsconfiginfo where configName like ?)
stmt.setString(1,"%"+serviceNameKeyword+"%");是标准写法, 以免后来者误解
5 楼 gufenglian 2009-10-30  
liweixw 写道
stmt = con.prepareStatement(select serviceCode from smsconfiginfo where configName like '%?%')

改成
stmt = con.prepareStatement(select serviceCode from smsconfiginfo where configName like ?)
stmt.setString(1,"%"+serviceNameKeyword+"%");

这样不优雅点。  呵呵。。

理解下预编译语句区别就知道你犯这错误的原因了、。



呵呵,谢谢了,有时就是脑子转不过弯,谢谢分享。
4 楼 liweixw 2009-10-29  
stmt = con.prepareStatement(select serviceCode from smsconfiginfo where configName like '%?%')

改成
stmt = con.prepareStatement(select serviceCode from smsconfiginfo where configName like ?)
stmt.setString(1,"%"+serviceNameKeyword+"%");

这样不优雅点。  呵呵。。

理解下预编译语句区别就知道你犯这错误的原因了、。

3 楼 gufenglian 2009-07-13  
ranLoD 写道
错误没了。。也查不出东西了吧?

怎么会查不出东西呢?
我这个是解决问题之后才写的博客。你可以说说具体情况
2 楼 ranLoD 2009-07-11  
错误没了。。也查不出东西了吧?
1 楼 ranLoD 2009-07-10  
恩,谢谢MM,今天我也遇到这个问题了呢

相关推荐

    spring自带的jdbcTemplate查询、插入预编译使用

    简单的jdbcTemplate预编译、回调等

    终于搞懂了,预编译头文件

    预编译头文件 <br>今天在改一个很大的程序,慢慢看,慢慢改。突然发现一个.c文件,里面什么也没有, <br>就几个头文件,我一看,我靠,这不是把简单的问题搞复杂了吗,随手删掉那个c文件。 <br>结果不能...

    各种C++预编译命令

    c编程中经常用到的各种常见的预编译命令。

    预编译资料- 预编译资料

    C语言的编译系统分为编译预处理和正式编译,这是C 语言的一大特点,其中编译预处理是它和其他高级语言的一个重要区别。编译C语言程序时,编译系统中首先是编译预处理模块根据预处理命令对源程序进行适当的处理,然后...

    预编译头的概念的介绍

    所谓的预编译头就是把一个工程中的那一部分代码,预先编译好放在一个文件里(通常是以.pch为扩展名的),这个文件就称为预编译头文件,这些预先编译好的代码可以是任何的C/C++代码--------甚至是inline的函数,但是必须...

    关于预编译头文件

    预编译头文件说明 C/C++头文件一览 预处理的由来 常见的预处理功能 预处理指令 文件包含指令

    预编译命令大全

    预编译命令大全; 讲述C语言各种预编译命令,详解,非常有用。

    Mesa 17.0.0 Windows预编译dll

    开始我有个特殊应用方式需要用到Mesa,但是找了很久都没找到新的能用的预编译dll。自己尝试了在本机Win10、虚拟机Ubuntu、云服务器Ubuntu、云服务器Server 2012 R2上编译,结果都是失败的。只在云服务器Ubuntu上编译...

    什么是预编译

    什么是预编译?对预编译的解释。对新手学习编程语言的一些基础帮助。

    几个预编译指令的用法

    几个预编译指令的用法

    linux C++ 预编译

    linux C++ 预编译 cmake样例

    JAVA预编译示例代码

    JAVA预编译示例代码,包括1预编译中使用like 2javaSQL预编译异常 3预编译语句支持in方式 4在预编译中遇到的问题.有了这个文档,java预编译就不用再发愁了。

    Osg预编译包

    自己编译的OSG3.0.0版本的预编译包,可以直接使用,缩短OSG的开发时间。

    预编译资料 预编译资料

    预编译资料 经典预编译资料经典预编译资料经典预编译资料经典预编译资料

    MySQL预编译功能

    MySQL预编译功能

    openssl-3.0.0预编译二进制开发包

    1、openssl3.0.0预编译二进制开发包SDK 2、Windows环境下基于Visual Studio2017编译 3、该资源是64位,无32位

    js--预编译顺序和原理

    js--预编译顺序和原理 | js--预编译顺序和原理 | js--预编译顺序和原理 | js--预编译顺序和原理 | js--预编译顺序和原理 | js--预编译顺序和原理 | js--预编译顺序和原理

    c语言的预编译处理

    预编译处理虽然不难,但是学好C语言最好能弄懂预编译

    C语言的 预编译 教程 详解

    c语言预编译教程,比较详细,好不好看后便知,免费分享

    C++预编译指令用法

    c++几个预编译指令用法:#undef ,#ifdef,#ifndef,#if

Global site tag (gtag.js) - Google Analytics