查看: 120444|回复: 11

[精华] 求助:DB2 SQLCODE=-302, SQLSTATE=22001的问题

[复制链接]
论坛徽章:
1
优秀写手
日期:2014-12-06 06:00:15
跳转到指定楼层
1#
发表于 2014-7-11 10:15 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
最近在开发过程中,遇到了com.ibm.db2.jcc.am.SqlDataException: DB2 SQL Error: SQLCODE=-302, SQLSTATE=22001, SQLERRMC=null, DRIVER=4.17.29的异常。情况是这样的:
现在数据库中有一张表A,表A中有一个字段a,类型长度为varchar(5),我用简单的JDBC对表A进行查询操作;
1、当我使用PreparedStatement的预编译的模式,即:PreparedStatement ps = conn.prepareStatement("select * from A where a=?");ps.setString(1, "1790000001x");时,会报出上述的异常;
2、当我使用PreparedStatement的非预编译的模式,即:PreparedStatement ps = conn.prepareStatement("select * from A where a='xxxxxx'");时,能够正常执行;
我上述操作是在DB2 10.5下进行的,用的Driver用的时DB2 10.5自带的db2jcc4.jar.
当我把数据库换为DB2 10.1 expc linux64后,两种PreparedStatement的代码并没有报错,此时我用的Driver并没有更换。
我在使用DB2 ? SQL302命令,查到如下信息:
xxx@xxxi-virtual-machine:~$ db2 ? SQL302




SQL0302N  EXECUTE 或 OPEN 语句中主变量的值超出了其相应的使用范
      围。


说明:


发现输入主变量的值对于其在 SELECT、VALUES 或预编译语句中的使用而言已超
出了范围。


发生了下列情况之一:


*  SQL 语句中使用的相应主变量或参数标记被定义为字符串,但是输入主变量包
   含的字符串太长。
*  SQL 语句中使用的相应主变量或参数标记被定义为数字,但是输入主变量包含
   的数值超出了范围。
*  C 语言以 NUL 终止的字符串主变量中丢失终止字符 NUL。
*  联合系统用户:在传递会话中,可能违反了特定于数据源的限制。


由于在 EXECUTE 或 OPEN 语句上的 SQLDA 中指定了不正确的主变量或不正确的
SQLLEN 值,因此发生此错误。


无法处理该语句。


用户响应:


确保输入主变量值的类型和长度正确。


如果输入主变量向参数标记提供值,那么使这些值与参数标记的隐含数据类型和
长度相匹配。


联合系统用户:对于传递会话,请确定导致该错误的数据源。


检查该数据源的 SQL 方言以确定违反了哪个特定限制,并根据需要来调整失败的
语句。


sqlcode:-302


sqlstate:22001, 22003




   相关信息
   数据源连接错误故障诊断



按着官方的解释,我将查询条件改为长度为5的字符串,两个版本的数据库都会正常执行。

这种情况(不同版本的数据库在这个问题上表现不同)是因为数据库版本的问题吗?如果是这样,有办法在数据库层面解决这个问题吗?

论坛徽章:
1
技术图书徽章
日期:2014-01-24 10:18:55
2#
发表于 2014-7-16 21:24 | 只看该作者
很有意思的一个报错试验,有时间我认真研究一下。

首先预编译和非预编译我也觉得有点疑惑。JDBC用的都是动态SQL,所以用PreparedStatement来预编译并重复使用编译好的Access Plan,应该跟是否使用Parameter Marker (?)无关。

其次就是Driver版本不同的确可能会有一定的区别。

看了如下参考文章,也许有帮助:
http://docs.oracle.com/javase/7/ ... paredStatement.html
http://javarevisited.blogspot.ca ... t-in-java-jdbc.html
http://blog.csdn.net/xiyuan1999/article/details/8443819

使用道具 举报

回复
论坛徽章:
1
优秀写手
日期:2014-12-06 06:00:15
3#
 楼主| 发表于 2014-12-3 16:34 | 只看该作者
mingongyi 发表于 2014-7-16 21:24
很有意思的一个报错试验,有时间我认真研究一下。

首先预编译和非预编译我也觉得有点疑惑。JDBC用的都是 ...

谢谢,问题已解决,设置环境变量DB2_DEFERRED_PREPARE_SEMANTICS=YES   
http://book.51cto.com/art/201112/310691.htm

使用道具 举报

回复
论坛徽章:
5
慢羊羊
日期:2015-03-04 14:55:272015年新春福章
日期:2015-03-06 11:59:47喜羊羊
日期:2015-04-02 19:59:02懒羊羊
日期:2015-05-17 21:03:29懒羊羊
日期:2015-05-20 20:04:36
4#
发表于 2014-12-4 09:26 | 只看该作者
引用自http://book.2cto.com/201306/25702.html
DB2 V10现在已经有所改进,即使缓存中的准备语句是使用硬编码直接量建立的,对于其他包含不同值的查询,DB2 V10现在也能重用缓存中的这个准备语句。V10把动态语句缓存称为直接量替换(literal replacement)。由于DB2能够识别出一个SQL与之前的SQL相同(只是直接量值有所不同),这样就能大大减少实现语句重用所需的工作。如果一个应用在SQL语句中使用了大量直接量,就可以采用很多方法来启用这个特性。

也就是V10版可以不用参数变量或者少用。
1:select * from A where a='v1'
2:select * from A where a='v2'

现在对于第二句,系统会自动复用第一句生成的执行计划。

使用道具 举报

回复
论坛徽章:
1
优秀写手
日期:2014-12-06 06:00:15
5#
 楼主| 发表于 2014-12-4 11:47 | 只看该作者
komicakomica 发表于 2014-12-4 09:26
引用自http://book.2cto.com/201306/25702.html
DB2 V10现在已经有所改进,即使缓存中的准备语句是使用硬编 ...

谢谢,你的回复和我之前的问题貌似没什么关系,呵呵。但是还是非常感谢这个有意义的建议

使用道具 举报

回复
认证徽章
论坛徽章:
3
蓝锆石
日期:2015-02-03 13:52:43沸羊羊
日期:2015-03-04 14:55:412015年新春福章
日期:2015-03-06 11:59:47
6#
发表于 2015-1-11 12:09 | 只看该作者
谢谢分享      

使用道具 举报

回复
论坛徽章:
0
7#
发表于 2015-3-9 03:40 | 只看该作者
嘿嘿。。这个问题。。

使用道具 举报

回复
论坛徽章:
0
8#
发表于 2015-4-2 01:43 | 只看该作者
嘿嘿。。这个问题。。

使用道具 举报

回复
论坛徽章:
0
9#
发表于 2015-4-11 15:53 | 只看该作者
我无能为力咯!

使用道具 举报

回复
bossmp3 该用户已被删除
10#
发表于 2015-4-12 03:23 | 只看该作者
这个你应该上百度搜搜看看

使用道具 举报

回复

您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

TOP技术积分榜 社区积分榜 徽章 团队 统计 知识索引树 积分竞拍 文本模式 帮助
  ITPUB首页 | ITPUB论坛 | 数据库技术 | 企业信息化 | 开发技术 | 微软技术 | 软件工程与项目管理 | IBM技术园地 | 行业纵向讨论 | IT招聘 | IT文档
  ChinaUnix | ChinaUnix博客 | ChinaUnix论坛
CopyRight 1999-2011 itpub.net All Right Reserved. 北京盛拓优讯信息技术有限公司版权所有 联系我们 
京ICP备09055130号-4  北京市公安局海淀分局网监中心备案编号:11010802021510 广播电视节目制作经营许可证:编号(京)字第1149号
  
快速回复 返回顶部 返回列表