oracle中WMSYS.WM_CONCAT函数的版本差异
昨天在测试的时候发现,开发人员写的一段程序放在开发库中是好的,但是放在测试库中就会有问题。开发人员一直找不到问题的原因在哪里。于是就花了点时间协助开发人员来找问题的根本原因。
通过一些技术手段,定位到问题是由一个SQL语句引起的。
SQL语句如下:
WITH PXQ_TASK_TEMP AS
(SELECT A.DISTRIBUTE_DATE,
A.APP_NO,
A.TASK_ID,
A.TASK_NO,
A.ACTUAL_DISTRIBUTE_DATE,
A.ACTUAL_RETURN_DATE,
A.RELA_ID RELAID,
A.VEHICLE_SERIAL,
A.STATUS_CODE,
A.MONTH,
A.MADE_DPET_NO,
A.DIST_TYPE_CODE,
A.TASK_TYPE,
A.RETURN_DATE,
B.SOURCE_NODE_ID,
B.RCV_NODE_NAME,
B.RCV_NODE_ID,
B.RCV_ID,
C.DET_ID,
C.EQUIP_CATEG,
C.TASK_NUM,
D.RELA_ID
FROM D_DISTRIBUTE_TASK A,
D_RCV_TASK B,
D_DIST_TASK_DET C,
ECMS.D_VEHICLE_TASK_RELA D
WHERE A.TASK_ID = B.TASK_ID(+)
AND B.RCV_ID = C.RCV_ID(+)
AND A.TASK_ID = D.TASK_ID(+)),
PXQ_TASK_CATEG AS
(SELECT DISTINCT TASK_ID, RCV_ID, DET_ID, EQUIP_CATEG, TASK_NUM
FROM PXQ_TASK_TEMP),
PXQ_TASK_SUM AS
(SELECT V.NAME || ':' || SUM(TASK_NUM) TASK_SUM, MAX(PXQ.TASK_ID) TASK_ID
FROM V_SP_CODE V, PXQ_TASK_CATEG PXQ
WHERE CODE_TYPE LIKE 'equipCateg'
AND VALUE = EQUIP_CATEG
GROUP BY PXQ.TASK_ID, V.NAME)
SELECT DISTINCT AA.DISTRIBUTE_DATE PLAN_DATE,
AA.APP_NO,
AA.MONTH,
AA.TASK_ID,
AA.TASK_NO,
AA.ACTUAL_DISTRIBUTE_DATE,
AA.ACTUAL_RETURN_DATE,
AA.RELAID,
AA.VEHICLE_SERIAL EV_NO,
AA.STATUS_CODE,
AA.DIST_TYPE_CODE,
AA.TASK_TYPE,
AA.RETURN_DATE,
(SELECT REPLACE(WMSYS.WM_CONCAT(NODE_NAME), ',', ';')
FROM ECMS.D_DISTRIBUTE_NODE
WHERE NODE_ID IN (SELECT DISTINCT SOURCE_NODE_ID
FROM PXQ_TASK_TEMP
WHERE TASK_ID = AA.TASK_ID)) SOURCE_NODE,
(SELECT REPLACE(WMSYS.WM_CONCAT(NODE_NAME), ',', ';')
FROM ECMS.D_DISTRIBUTE_NODE
WHERE NODE_ID IN (SELECT DISTINCT RCV_NODE_ID
FROM PXQ_TASK_TEMP
WHERE TASK_ID = AA.TASK_ID)) RCV_NODE,
(SELECT REPLACE(WMSYS.WM_CONCAT(TASK_SUM), ',', '/')
FROM PXQ_TASK_SUM
WHERE TASK_ID = AA.TASK_ID) PLAN_NUM,
'' EV_NUM,
'' SETTED_EV
FROM PXQ_TASK_TEMP AA
WHERE 1 = 1;
把这个SQL语句放在开发库可以正常执行,但是放在测试库就报错了。报错信息为:ORA-00932:数据类型不一致:应为 -,但却获得CLOB。当时想到的就是两个库中可能有些表的数据库数据结构不一致(如:字段的数据类型),经比较这个SQL语句中涉及到的表在两个环境中的数据结构完全一致。这时想到的就是可能是某个函数导致了结果出现了LOB类型。经诊断是由oracle函数WMSYS.WM_CONCAT引起的。那么为什么会引起这样的问题呢?两套环境同样是使用的oracle,程序也完全一致。首先想到的是可能oracle的WMSYS.WM_CONCAT函数存在版本差异。
下面就进行了WMSYS.WM_CONCAT函数在oracle版本差异的验证。在开发库中执行SELECT * FROM v$version;显示结果为:Oracle Database 10g Enterprise Edition Release 10.2.0.4.0 - 64bi;再在测试库中执行SELECT * FROM v$version;显示结果为:Oracle Database 10g Enterprise Edition Release 10.2.0.5.0 - 64bi。说明oracle版本差异的猜测是对的。
接下来看WMSYS.WM_CONCAT函数在不同oracle版本中到底存在什么差异。
编写测试SQL:
SELECT REPLACE(WMSYS.WM_CONCAT(NODE_NAME), ',', ';') FROM ECMS.D_DISTRIBUTE_NODE A WHERE NODE_ID IN (SELECT DISTINCT SOURCE_NODE_ID FROM D_RCV_TASK B);
该SQL在开发库中(即oracle版本为:Oracle Database 10g Enterprise Edition Release 10.2.0.4.0 - 64bi)执行结果为:

该SQL在测试库中(即oracle版本为:Oracle Database 10g Enterprise Edition Release 10.2.0.5.0 - 64bi)执行结果为:

oracle的WMSYS.WM_CONCAT函数在Oracle Database 10g Enterprise Edition Release 10.2.0.4.0 - 64bi版本中的结果是一个字符型的数据,而在Oracle Database 10g Enterprise Edition Release 10.2.0.4.0 - 64bi版本中是一个CLOB类型。而我们知道在SQL语句中若查询了LOB字段是不能使用distinct,union,和group by等关键字的。这样就完全解释了那个SQL语句会在测试库中报错的原因了。
最后将上面的SQL语句做了相关优化,且在不同oracle版本中通用。SQL语句修改后如下:
SELECT A.DISTRIBUTE_DATE PLAN_DATE,
A.APP_NO,
A.MONTH,
A.TASK_ID,
A.TASK_NO,
A.ACTUAL_DISTRIBUTE_DATE,
A.ACTUAL_RETURN_DATE,
A.RELA_ID,
A.VEHICLE_SERIAL EV_NO,
A.STATUS_CODE,
A.DIST_TYPE_CODE,
A.TASK_TYPE,
A.RETURN_DATE,
(SELECT REPLACE(WMSYS.WM_CONCAT(NODE_NAME), ',', ';')
FROM ECMS.D_DISTRIBUTE_NODE
WHERE NODE_ID IN (SELECT DISTINCT SOURCE_NODE_ID
FROM D_RCV_TASK
WHERE TASK_ID = A.TASK_ID)) SOURCE_NODE,
(SELECT REPLACE(WMSYS.WM_CONCAT(NODE_NAME), ',', ';')
FROM ECMS.D_DISTRIBUTE_NODE
WHERE NODE_ID IN (SELECT DISTINCT RCV_NODE_ID
FROM D_RCV_TASK
WHERE TASK_ID = A.TASK_ID)) RCV_NODE,
(SELECT REPLACE(WMSYS.WM_CONCAT(V.NAME || ':' || SUM(C.TASK_NUM)),
',',
'/')
FROM V_SP_CODE V, D_DIST_TASK_DET C
WHERE C.TASK_ID = A.TASK_ID
AND V.CODE_TYPE LIKE 'equipCateg'
AND V.VALUE = C.EQUIP_CATEG
GROUP BY V.NAME) PLAN_NUM,
'' EV_NUM,
'' SETTED_EV
FROM D_DISTRIBUTE_TASK A, ECMS.D_VEHICLE_TASK_RELA B
WHERE A.TASK_ID = B.TASK_ID(+)
GROUP BY A.DISTRIBUTE_DATE,
A.APP_NO,
A.MONTH,
A.TASK_ID,
A.TASK_NO,
A.ACTUAL_DISTRIBUTE_DATE,
A.ACTUAL_RETURN_DATE,
A.RELA_ID,
A.VEHICLE_SERIAL,
A.STATUS_CODE,
A.DIST_TYPE_CODE,
A.TASK_TYPE,
A.RETURN_DATE;
通过这次问题的排查,我们知道在写SQL语句的时候,若使用了WMSYS.WM_CONCAT函数,应尽量不要对查询结果进行distinct,union,和group by操作,避免oracle版本的差异化。
转载请注明文章来源于:http://www.cnblogs.com/Automation_software/archive/2013/03/29/2988333.html
oracle中WMSYS.WM_CONCAT函数的版本差异的更多相关文章
- 【Oracle】wmsys.wm_concat函数字段值为空
这个是因为字符集的问题,和空值是没关系的.其实已经取到了数据,可以验证一下返回的不是0,但是由于这个里面有个chr(0)字符,而且可能第一个字符就是chr(0),所以就显示得怪异的空现象.至于为何会出 ...
- Oracle 中wmsys.wm_concat拼接字符串,结果过长报错解决
备忘:这个函数最大是4000,根据拼接列的长度,通过限制拼接条数来防止拼接字符串过长错误 --这个情况是从子表中读取出具,这里直接把它当做查询字段处理,在子表中有所有数据 select info.id ...
- oracle 12C wmsys.wm_concat()函数
http://blog.itpub.net/31392094/viewspace-2149577/
- Oracle中的单行函数
Oracle中的单行函数 1 字符函数 UPPER()--将字符串转换为大写 SELECT UPPER('abc') FROM dual; LOWER()-将字符串转换为小写 SELECT LOWER ...
- oracle 10g WMSYS.WM_CONCAT 函數的用法
select t.rank, t.Name from t_menu_item t; 10 CLARK 10 KING 10 MILLER 20 ADAMS 20 FORD 20 JONES 20 SC ...
- Oracle中 Instr 这个函数
http://www.jb51.net/article/42369.htm sql :charindex('字符串',字段)>0 charindex('administrator',MUserI ...
- 创建类似于Oracle中decode的函数
-- 创建类似于Oracle中decode的函数create or replace function decode(variadic p_decode_list text[])returns text ...
- Oracle中的substr()函数 详解及应用
注:本文来源于<Oracle中的substr()函数 详解及应用> 1)substr函数格式 (俗称:字符截取函数) 格式1: substr(string string, int a, ...
- MySQL之实现Oracle中的rank()函数的功能
假设表格为student, 数据如下: 我们要在MySQL中实现Oracle中的rank()函数功能,即组内排序,具体来说: 就是对student表中按照课程(course)对学生(name) ...
随机推荐
- JavaScript中数据类型的转换规则
JavaScript中数据类型的转换规则 制作人:全心全意 JavaScript是一种无类型语言,也就是说,在声明变量时无须指定数据类型,这使得JavaScript更具有灵活性和简单性. 在代码执行过 ...
- LINUX系统---中级相关操作和知识
LINUX系统的中级,来搞一些LINUX安全相关的东西,还有在公司生成中长搞的集群. RHCS集群 什么是高可用 什么是热备 什么是分布式
- HDU 1800 hash 找出现最多次数的字符串的次数
乘法hash: 这类hash函数利用了乘法的不相关性 int Hash(char *str){ int seed = 131 , value=0; while(*str != '\0'){ ...
- HDU 5643 King's Game 【约瑟夫环】
题意: 变形的约瑟夫环,最初为每个人编号1到n,第i次删去报号为i的人,然后从它的下一个人开始重新从1开始报号,问最终剩下第几号人? 分析: 首先看一下裸的约瑟夫环问题: 共n个人,从1开始报数,报到 ...
- POJ 3233_Matrix Power Series
题意: 求n*n矩阵的幂和 分析: 逐个加起来时间复杂度太高,通过在矩阵中套个矩阵和,再利用矩阵快速幂,最后时间复杂度为O(n3logn) 代码: #include<cstdio> #in ...
- mac idea快捷键(部分常用)
shift+F6重命名 shift+enter 换到下一行 shift+F8等同eclipse的f8跳到下一个断点,也等同eclipse的F7跳出函数 F8等同eclipse的f6跳到下一步F7等同e ...
- 洛谷 P1023 税收与补贴问题
P1023 税收与补贴问题 题目背景 每样商品的价格越低,其销量就会相应增大.现已知某种商品的成本及其在若干价位上的销量(产品不会低于成本销售),并假设相邻价位间销量的变化是线性的且在价格高于给定的最 ...
- Ubuntu 16.04下SecureCRT无法输入中文的解决思路
说明:首先网上的方法基本都是不行的,别试了. 但是可以有弥补方案: 1.通过外界的软件编辑好中文,然后粘贴过去.虽然是多了一步,但是也可以输入中文. 2.关于这个问题应该是没有中文字体库导致的,可以尝 ...
- Ubuntu 16.04错误:正在读取软件包列表... 有错误! E: Encountered a section with no Package: header E: Problem with MergeList /var/lib/apt/lists/ppa.launchpad.net_t-tujikawa_ppa_ubuntu_dists_xenial_main_i18n_Translatio
错误: 正在读取软件包列表... 有错误! E: Encountered a section with no Package: header E: Problem with MergeList /va ...
- maven提示“编码 GBK 的不可映射字符”问题的解决
pom.xml中加上如下代码 <properties> <!-- spring版本号 --> <spring.version>4.2.3.RELEASE</s ...