`
gufenglian
  • 浏览: 51043 次
  • 性别: 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查询、插入预编译使用

    `是预编译的占位符,`params`数组包含了实际参数,`MyRowMapper`是一个自定义的映射器,用于将查询结果转换为Java对象。 接下来,让我们看看如何使用`jdbcTemplate`进行预编译的插入操作。`update()`方法可以用来...

    Osg预编译包

    OSG 3.0.0是OpenSceneGraph的一个重要版本,它带来了许多新特性和改进。这个版本可能包含了以下关键更新: 1. **性能优化**:在3.0.0版本中,开发者通常会关注性能的提升,包括更快的渲染速度、更高效的内存管理等...

    Mesa 17.0.0 Windows预编译dll

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

    c#加壳 模糊 反编译.rar

    接下来,"Sixxpack24.zip"可能包含的是一个加壳工具,如Sixxpack,用于将程序的原始二进制代码包装在一个外壳程序中。加壳技术能够隐藏程序的真实入口点,增加逆向工程的难度。外壳程序通常会执行一些验证步骤,如...

    FpcupDeluxe国内加速预编译版

    fpcupdeluxe是一个帮助快速建立起开发环境和交叉编译环境的辅助工具,由于git下载速度极慢切容易掉线,严重影响了fpcupdeluxe的使用。为此,我修改了部分源码,加入了镜像加速功能,预编译了win和linux下64和32位的...

    c语言容易出错的地方

    C编译的程序对语法检查并不象其它高级语言那么严格,这就给编程人员留下“灵活的余地”,但还是由于这个灵活给程序的调试带来了许多不便,尤其对初学C语言的人来说,经常会出一些连自己都不知道错在哪里的错误。...

    C++中预编译头文件stdafx.h

    在C++编程环境中,预编译头文件`stdafx.h`是一个常见的概念,特别是在使用Microsoft Visual Studio等IDE时。这个头文件的主要目的是为了提高编译效率,通过预编译一些经常改变但不常重新编译的代码,从而减少编译...

    qtwebengine编译模块

    qt安装自带的qtwebengine不支持视频,要支持需要自己使用-webengine-proprietary-codecs编译。编译时间很长,很容易出错。这里提供vs2019编译的64位版本。qt5.15.0版本的qtwebengine

    编译原理答案(编译原理及编译程序构造)

    语法分析从词法分析程序取得源程序,并将一个或多个单词组合为语言的各种语法类;语义分析确定源程序的意义(语义);代码生成将源程序的中间形式转化为汇编语言或机器语言;代码优化获得更高效的目标程序;出错处理...

    很不错的dll反编译工具

    DLL(Dynamic Link Library)是Windows操作系统中的一个重要组成部分,它封装了可重用的函数和资源,供多个程序共享。在编程领域,有时我们需要查看或理解DLL文件内部的代码逻辑,这时就涉及到了“反编译”技术。反...

    windows下编译好的openssl

    总的来说,这个压缩包提供了一个方便的解决方案,让Windows开发者能够快速在32位系统上集成OpenSSL功能,而无需自己处理编译和依赖问题。使用这个预编译的版本可以节省时间,特别是对于那些不熟悉OpenSSL编译过程的...

    C# 反编译NET_IL命令查询器

    标题中的"C# 反编译NET_IL命令查询器"指的是一个工具或软件,它主要用于查看和解析C#程序集中的中间语言(IL)指令。中间语言是.NET框架的一部分,它是源代码编译后的二进制表示,介于高级语言(如C#)和机器码之间...

    windows下编译好的Zint库

    Zint库是一个开源项目,主要用于生成各种类型的条形码和二维码。这个压缩包包含了在Windows环境下编译好的Zint库的动态链接库(dll)和库文件(lib),分为release和debug两个版本,以满足不同开发需求。 1. **Zint...

    DELPHI7编译出错提示内存:RLINK32.dll出错

    delphi7编译慢 或linking阶段会出错 经常会出现内存泄漏或不足 或RLink32.DLL访问出错 直接把bolndmm.dll与rlink32.dll拷贝至delphi7下的bin目录中可以调试了 按网友的说法 新版的内存管理器或连接器 bolndmm.dll...

    VB生成的EXE文件反编译

    1. "红色黑客联盟 软件说明.htm" - 这可能是一个关于反编译工具或相关软件的使用说明文档,详细介绍了软件的功能、操作步骤和注意事项。 2. "优秀投稿动画奖励计划.txt" - 这可能是某个社区或平台的奖励计划,可能与...

    EA反编译 EX4反编译MQ4

    在描述中提到的文件"ex4 to mq4"很可能是一个反编译工具或者教程,帮助用户进行`.ex4`到`.mq4`的转换。使用这样的工具时,应确保遵循以下步骤: 1. 下载并安装反编译软件,如"Ex4ToMq4"。 2. 将`.ex4`文件拖放到...

    DeDe反编译工具

    总之,DeDe反编译工具是Delphi开发者的一个强大工具,它打开了理解Delphi程序内部构造的大门,使得学习和研究变得更为直观。但同时也提醒我们在使用此类工具时,应遵守法律法规,尊重他人的劳动成果。在技术进步的...

    已经编译好的Openssl

    【标题】"已经编译好的Openssl"指出的是一个预编译的OpenSSL软件包,这个包包含了在Windows 7环境下可以直接使用的OpenSSL库和工具。OpenSSL是一个强大的安全套接字层密码库,含有各种主要的密码算法、常用的密钥和...

    编译原理课后习题答案

    - 过程:从一个简单的核心语言开始,通过不断扩展语言特性和编写相应的编译程序,最终达到所需的语言级别。 - 例子:逐步扩展语言特性,如从L0扩展到L1,再到L2等。 以上是对《编译原理》课程中一些基础知识和...

Global site tag (gtag.js) - Google Analytics