Focus On Oracle

Installing, Backup & Recovery, Performance Tuning,
Troubleshooting, Upgrading, Patching

Oracle Engineered System


当前位置: 首页 » 技术文章 » 案列分析

wmsys.wm_concat的坑,你中了么?

问题描述
客户的管理系统采用BS的架构,包括Web应用(Windows平台)和数据库(AIX 5.3),
Web应用:Oracle 10g客户端 + IIS7(配置了ODBC)
数据库:Oracle 10.2.0.1(AIX)

当把数据库升级迁移到11.2.0.4(Solaris 11)之后,客户系统运行正常,除了一个网页有问题,显示错误如下
Microsoft OLE DB Provider for Oracle 错误 ‘80004005’
数据类型不被支持
/vendor/order.asp ,行102


问题分析
看到这个错误,想着可能是windows平台上客户端的问题,因为刚把数据库从10.2.0.1升级到11.2.0.4,数据库在数据类型方面或许有些小的变更
于是和客户沟通,让客户升级web服务器上Oracle客户端的版本,从10.2.0.1升级到11.2.0.1。

在过了一个多小时焦急的等待,客户打电话说:"我们在更糟了,升级之后,网站彻底不能用了"。生产系统,现在只能立即去现场了。到底现场后,查看数据库正常,然后通过"事件查看器"查看,发现切换到11g库之后,IIS的错误信息更多了,之前没有这些错误信息
错误:脚本引擎异常.ScriptEngine引发了异常"c0000005"(位于 "IScriptDispatchEx::Release()"中,来自"CScriptingNamespace::UnInit()" )。

查了一些相关信息,说可能是Windows脚本解析器的问题,需要升级(对IIS这些事情,咱还是不专业,通过这个途径可能更慢),适用的版本是Windows 2003,这个与客户操作系统版本不一致,还有就是升级Oracle客户端之前正常,升级后异常,果断决定卸载11g客户端,仍用10g的客户端。很幸运,重新使用10g的客户端之后,IIS启动正常,网站正常,除了还是之前的那个页面。

继续查看这个错误,仔细看了下,提到了文件名字及行号。打开文件order.asp,终于找到了对应的语句:里面用了wm_concat,开发人员为了省事,用了wm_concat
经查询发现WMSYS.WM_CONCAT函数,在不同版本返回不同的值,恍然大悟,一定是这个问题

解决问题
10g的客户端 + 11g的数据库,10.2.0.1中返回的是varchar,然后在11.2.0.4中返回的是CLOB。
有三种方案解决这个问题
A.还使用10g的库,但是在Solaris 11上安装不了10g的库,除了新建ZONE
B.使用11g(11.2.0.1)的库,这种可行,但是时间上不允许
C.使用函数to_char()把clob转化为varchar,此workaround方法最快,也最省事

函数WMSYS.WM_CONCAT在11.2.0.2和10.2.0.5以上的版本使用CLOB
10.2.0.5, 11.2.0.2+版本返回的是clob
FUNCTION wm_concat( P1 VARCHAR2 IN ) RETURNS CLOB.

10.2.0.4-, 11.1.0.7-, 11.2.0.1返回的是varchar2
FUNCTION wm_concat( P1 VARCHAR2 IN ) RETURNS VARCHAR2

总结

虽然解决了这个问题,但还是走了点弯路。解决问题,要切中要害,眼见为实(如果直接查看文件order.asp 102行,可能耗时会更少),有时候经验会害人。不要图懒省事(wm_concat这个是Oracle内部使用的,所以在官方文档上是找不到这个函数的),尽量自己去做,这样风险可控。





关键词:oracle 

相关文章

基于PDB的Active Data Guard(Oracle 21.7+)
在Oracle数据库中使用REST
OGG from MySQL to Oracle
Oracle数据库容灾之两地三中心实践
低代码开发用Oracle Apex,看这篇就够了
Oracle Database 20c之SQL宏
Java beginner for Oracle DBA
Oracle Database 20c之区块链表
Oracle Database 20c的一些微妙变化
关于Oracle的Sequence,你需要知道的
Oracle数据库优化方面资料
Oracle Database 19c在优化方面有哪些新特性
Top