引起语句多版本的一个原因。下面做了一个测试来演示这种情况,线上很多库上都有类似的问题。
ibatis版本:2.3.0
oracle版本:10.2.0.4
1. 建临时表
create table tmp_jd_bind_test(id number, c1 number, c2 date);
2. java 端调用程序,用ibatis, 插入记录, 这一步是雷卷配合帮忙做的,非常感谢雷卷
<insert id="SkinDAO.insertCheck" parameterClass="java.util.Map">
insert into tmp_jd_bind_test(id, c1, c2) values(#id#, #c1#, #c2#)
</insert>
public void testCheck() throws Exception {
Map<String, Object> params = new HashMap<String, Object>();
params.put("id", 1);
skinDAO.insertCheck(params);
params.put("c1", 0);
skinDAO.insertCheck(params);
params.put("c2", new Date());
skinDAO.insertCheck(params);
params.remove("id");
skinDAO.insertCheck(params);
params.remove("c1");
skinDAO.insertCheck(params);
}
3. 看表里的数据
SQL> select * from tmp_jd_bind_test;
ID C1 C2
---------- ---------- ------------
1
1 0
1 0 12-JAN-10
0 12-JAN-10
12-JAN-10
4. 找到刚才执行的insert语句的sql_id --sql_id: aq45j8c82fg6n
aq45j8c82fg6n
insert into tmp_jd_bind_test(id, c1, c2) values(:1, :2, :3)
5. 看这个sql_id的多个子游标
SQL> select sql_id, child_address, child_number from v$sql where sql_id = 'aq45j8c82fg6n';
SQL_ID CHILD_ADDRESS CHILD_NUMBER
------------- ---------------- ------------
aq45j8c82fg6n 00000000B57BAEF8 0
aq45j8c82fg6n 00000000A5D45A28 1
aq45j8c82fg6n 00000000A5ADAD48 2
aq45j8c82fg6n 00000000B57A29E8 3
aq45j8c82fg6n 00000000924298F0 4
6. 查看这些子游标的绑定变量情况
SQL> select * from v$sql_bind_metadata where address in ('00000000B57BAEF8', '00000000A5D45A28', '00000000A5ADAD48', '00000000B57A29E8', '00000000924298F0') order by position, address;
ADDRESS POSITION DATATYPE MAX_LENGTH ARRAY_LEN BIND_NAME
---------------- ---------- ---------- ---------- ---------- ------------------------------
00000000924298F0 1 1 32 0 1
00000000A5ADAD48 1 2 22 0 1
00000000A5D45A28 1 2 22 0 1
00000000B57A29E8 1 1 32 0 1
00000000B57BAEF8 1 2 22 0 1
00000000924298F0 2 1 32 0 2
00000000A5ADAD48 2 2 22 0 2
00000000A5D45A28 2 2 22 0 2
00000000B57A29E8 2 2 22 0 2
00000000B57BAEF8 2 1 32 0 2
00000000924298F0 3 180 11 0 3
00000000A5ADAD48 3 180 11 0 3
00000000A5D45A28 3 1 32 0 3
00000000B57A29E8 3 180 11 0 3
00000000B57BAEF8 3 1 32 0 3
15 rows selected.
7. 总结一下规律
如果表里字段是number型的,用ibatis传一个null进来,会绑定成varchar2类型的,
如果表里字段是date型的,用ibatis传一个null进来,也会绑定成varchar2类型的。
8. 怎么解决这个问题?
这是接下来要考虑问题。
<insert id="SkinDAO.insertCheck" parameterClass="java.util.Map">
insert into tmp_jd_bind_test(id, c1, c2) values(#id#, #c1#, #c2#)
</insert>
这种写法容易导致多版本, 当传入的值为null时,ibatis不能判断出字段的类型
<insert id="SkinDAO.insertCheck" parameterClass="java.util.Map">
insert into tmp_jd_bind_test(id, c1, c2) values(#id:BIGINT#, #c1:BIGINT#, #c2:DATE#)
</insert>
通过在sqlmap文件中指定每个字段的类型,不会产生由于类型不匹配引起的多版本
分享到:
相关推荐
许多年来,我在不同的新闻组上花费了很多时间与那些想知道如何得到数据库管理员(DBA)的工作或者如何成长为一名DBA的IT人进行交谈,现在他们有了工作。这些年来许多人针对如何达到这个目标提出了不同意见。本文即是...
阿里巴巴招聘dba笔试题,很详细,想往dba方向发展的同学可以看看,挺好的
作者本人不仅专业技术过硬,还当过篮球教练,对人生,尤其是DBA 的生存之道有很独到的领悟... 本书汇集了作者有关数据库管理的真知灼见,讲述了DBA 的方方面面,有技术的,还有生活的。作者本人不仅专业技术过硬,还...
dba日记,感觉很有可读性,喜欢和想从事oracle的友友可以看看
其中包含了自己经历的一份面试笔试题(很难得),还有一些工作经验,总共5份文档,有一点点文件是转载的~~
书据库管理员,英文是Database Administrator,简称DBA。这个职位对不同的人意味着不同的意义。一个小的软件开发工作室和一个分工高度明细的大公司相比,DBA的职责来得更加宽泛一些。一个公司,不管它是自己开发应用...
成就DBA职业生涯_Grow That DBA Career
DBA最有用的数据库系统原理 知识
Oracle dba常用操作,很基础很详细。
招聘数据库DBA职位的库DBA面试题(知名外企)
Oracle DBA基础知识, DBA必备宝典!
DBA职责DBA职责DBA职责DBA职责DBA职责
DBA求职面试技巧 DBA求职面试技巧 DBA求职面试技巧
mysql dba 常用脚本 运行脚本可以方便管理MYSQL运行脚本可以方便管理MYSQL运行脚本可以方便管理MYSQL
DBA必须掌握的库表,很实用,属于dba的入门级别
DBA 攻坚 左手Oracle右手MySQL oneNote格式
DBA常用的命令集锦 DBA常用命令269条
很好很强大的oracle DBA入门教材。
DBA面试题 oracle 1:列举几种表连接方式 2:不借助第三方工具,怎样查看sql的执行计划....
LLM as DBA LLM as DBA LLM as DBA LLM as DBA LLM as DBA