该楼层疑似违规已被系统折叠 隐藏此楼查看此楼
Oracle 11g开发项目时,使用XML Table出现了BUG,现总结如下:问题其实很简单,就是我们在项目中使用了很多超级长的SQL语句,之后导致SQL执行效率低下,并且貌似导致了Oracle的SQL编译空间溢出了。
出问题的SQL:
以下是代码片段:
SELECT N1,N2
FROM A1
WHERE
(N1='1' AND N2='a1') OR
(N1='2' AND N2='a2') OR
(N1='3' AND N2='a3') OR
(N1='4' AND N2='a4') OR
....
BUG解析
当然了真实的SQL文是不可能这么简单的,比这个要复杂的多。不过出问题的部分基本就是这样了,其实原来没用AND/OR这种结构,用的是IN,但IN语句的参数不能超过2000个。所以就改成这个结构了,这个结构传东西到是没有限制了,但是会导致SQL文变长,而且由于数据的长度不定。这些1和a1是前面产生的结果,所以不一定有多少组。所以都是直接拼在SQL里了。问题很明显,后果很严重。
BUG解决
因为系统已经开发很长时间了,不能进行太大的改动。老系统就这样,改的越多,错的越多,狂改代码基本属于自虐行为。所以我们引入了XMLTable来解决这个问题,这还是一个DBA给的建议呢。
以下是代码片段:
SELECT N1,N2
FROM A1
WHERE (N1,N2) IN (
SELECT X1,X2 FROM
XMLTable('for $i in /T/REC return $i' PASSING XMLType(#str:CLOB#)
COLUMNS X1 INTEGER PATH 'X1',
X2 CHAR(2) PATH 'X2')
因为使用iBatis的缘故,所以我使用了一个叫str的参数,并且声明为CLOB类型的,但str里放什么呢?
以下是代码片段:
1a1
2a2
....
这个很明白了吧,就是把需要的数据通过XML的形式变成一个表,之后再和主表进行子查询进行关联。这样做的好处就是把SQL文的长度变换为参数的长度了,虽然参数变长了,但SQL文本身变短了。