客户的管理系统采用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内部使用的,所以在官方文档上是找不到这个函数的),尽量自己去做,这样风险可控。