今天客户现场业务甩给我一个报错让处理,ora-00904:"WM_CONCAT":标识符无效。

初步分析了下场景:

前天因为在原先一套库要删除,而他们业务用户A使用的便是该套计划删除的库,故导出A用户,导入到新环境中,expdp/impdp导入导出中均无报错。昨天在新环境给恢复成功,今天业务反映有报错,在新环境中查看确实没有该function,而老环境中有该function,但是是用户B的,猜测之前老环境是给A建立了B的synonym。

解决方法:

1、获取创建该函数的DDL语句,在新环境中直接创建该function

SQL>setlong999SQL>selectdbms_metadata.get_ddl('FUNCTION','WM_CONCAT','TBCS')fromdual;DBMS_METADATA.GET_DDL('FUNCTION','WM_CONCAT','TBCS')--------------------------------------------------------------------------------CREATEORREPLACEEDITIONABLEFUNCTION"TBCS"."WM_CONCAT"(P1VARCHAR2)RETURNclobAGGREGATEUSINGWM_CONCAT_IMPL;

执行DDL语句

SQL>CREATEORREPLACEEDITIONABLEFUNCTION"AOPEN"."WM_CONCAT"(P1VARCHAR2)RETURNclobAGGREGATEUSINGWM_CONCAT_IMPL;2/Warning:Functioncreatedwithcompilationerrors.SQL>

此操作后,明显报错了,让业务测试,肯定测不过,查看函数是无效的

SQL>selectOWNER,OBJECT_NAME,SUBOBJECT_NAME,OBJECT_TYPE,LAST_DDL_TIMEfromdba_objectswhereobject_name=upper('wm_concat');OWNEROBJECT_NAMESUBOBJECT_NAMEOBJECT_TYPELAST_DDL_TIME----------------------------------------------------------------------------------------------------------------------AWM_CONCATFUNCTION20191121172355SQL>

2、导出function在导入新环境

由于第一种方法不行,故考虑第二种方法,把老环境B用户的wm_concat函数迁移到新环境,测试可行否

导出function

expdp\'/assysdba\'directory=expdp_2019dumpfile=function_wm_concat_20191121.dmplogfile=function_wm_concat_expdp_20191121.logschemas=Binclude=function:\"IN\'WM_CONCAT\'\"Export:Release12.1.0.2.0-ProductiononThuNov2117:46:382019Copyright(c)1982,2014,Oracleand/oritsaffiliates.Allrightsreserved.Connectedto:OracleDatabase12cEnterpriseEditionRelease12.1.0.2.0-64bitProductionWiththePartitioning,AutomaticStorageManagement,OLAP,AdvancedAnalyticsandRealApplicationTestingoptionsStarting"SYS"."SYS_EXPORT_SCHEMA_02":"/********ASSYSDBA"directory=expdp_2019dumpfile=function_wm_concat_20191121.dmplogfile=function_wm_concat_expdp_20191121.logschemas=Binclude=function:"IN'WM_CONCAT'"EstimateinprogressusingBLOCKSmethod...TotalestimationusingBLOCKSmethod:0KBProcessingobjecttypeSCHEMA_EXPORT/FUNCTION/FUNCTIONProcessingobjecttypeSCHEMA_EXPORT/FUNCTION/ALTER_FUNCTIONMastertable"SYS"."SYS_EXPORT_SCHEMA_02"successfullyloaded/unloaded******************************************************************************DumpfilesetforSYS.SYS_EXPORT_SCHEMA_02is:/ora12c/oracle/dir_dump/function_wm_concat_20191121.dmpJob"SYS"."SYS_EXPORT_SCHEMA_02"successfullycompletedatThuNov2117:47:272019elapsed000:00:47

导入新环境,使用户转换,由B转换为A

impdp\'/assysdba\'directory=DIR_DUMPdumpfile=function_wm_concat_20191121.dmplogfile=function_wm_concat_impdp_20191121.logremap_schema=B:AImport:Release12.1.0.2.0-ProductiononThuNov2117:48:532019Copyright(c)1982,2014,Oracleand/oritsaffiliates.Allrightsreserved.Connectedto:OracleDatabase12cEnterpriseEditionRelease12.1.0.2.0-64bitProductionWiththePartitioning,AutomaticStorageManagement,OLAP,AdvancedAnalyticsandRealApplicationTestingoptionsMastertable"SYS"."SYS_IMPORT_FULL_01"successfullyloaded/unloadedStarting"SYS"."SYS_IMPORT_FULL_01":"/********ASSYSDBA"directory=DIR_DUMPdumpfile=function_wm_concat_20191121.dmplogfile=function_wm_concat_impdp_20191121.logremap_schema=B:AProcessingobjecttypeSCHEMA_EXPORT/FUNCTION/FUNCTIONProcessingobjecttypeSCHEMA_EXPORT/FUNCTION/ALTER_FUNCTIONORA-39082:ObjecttypeFUNCTION:"AOPEN"."WM_CONCAT"createdwithcompilationwarningsJob"SYS"."SYS_IMPORT_FULL_01"completedwith1error(s)atThuNov2117:49:002019elapsed000:00:05

查看函数状态,依旧invalid

SQL>selectowner,object_name,object_type,statusfromdba_objectswhereownernotin('SYS','SYSTEM')ANDstatus!='VALID';OWNEROBJECT_NAMEOBJECT_TYPESTATUS------------------------------------------------------------------------------------------AWM_CONCATFUNCTIONINVALID

3、手工创建该函数

考虑到第一种方法只是创建了function,而包体等内容并没有创建,故手工创建package、body、function

a、以sys用户创建包、包体、函数

CREATEORREPLACETYPEWM_CONCAT_IMPLASOBJECT(CURR_STRVARCHAR2(32767),STATICFUNCTIONODCIAGGREGATEINITIALIZE(SCTXINOUTWM_CONCAT_IMPL)RETURNNUMBER,MEMBERFUNCTIONODCIAGGREGATEITERATE(SELFINOUTWM_CONCAT_IMPL,P1INVARCHAR2)RETURNNUMBER,MEMBERFUNCTIONODCIAGGREGATETERMINATE(SELFINWM_CONCAT_IMPL,RETURNVALUEOUTVARCHAR2,FLAGSINNUMBER)RETURNNUMBER,MEMBERFUNCTIONODCIAGGREGATEMERGE(SELFINOUTWM_CONCAT_IMPL,SCTX2INWM_CONCAT_IMPL)RETURNNUMBER);

b、创建类型body

CREATEORREPLACETYPEBODYWM_CONCAT_IMPLISSTATICFUNCTIONODCIAGGREGATEINITIALIZE(SCTXINOUTWM_CONCAT_IMPL)RETURNNUMBERISBEGINSCTX:=WM_CONCAT_IMPL(NULL);RETURNODCICONST.SUCCESS;END;MEMBERFUNCTIONODCIAGGREGATEITERATE(SELFINOUTWM_CONCAT_IMPL,P1INVARCHAR2)RETURNNUMBERISBEGINIF(CURR_STRISNOTNULL)THENCURR_STR:=CURR_STR||','||P1;ELSECURR_STR:=P1;ENDIF;RETURNODCICONST.SUCCESS;END;MEMBERFUNCTIONODCIAGGREGATETERMINATE(SELFINWM_CONCAT_IMPL,RETURNVALUEOUTVARCHAR2,FLAGSINNUMBER)RETURNNUMBERISBEGINRETURNVALUE:=CURR_STR;RETURNODCICONST.SUCCESS;END;MEMBERFUNCTIONODCIAGGREGATEMERGE(SELFINOUTWM_CONCAT_IMPL,SCTX2INWM_CONCAT_IMPL)RETURNNUMBERISBEGINIF(SCTX2.CURR_STRISNOTNULL)THENSELF.CURR_STR:=SELF.CURR_STR||','||SCTX2.CURR_STR;ENDIF;RETURNODCICONST.SUCCESS;END;END;

c、创建函数

CREATEORREPLACEFUNCTIONwm_concat(P1VARCHAR2)RETURNVARCHAR2AGGREGATEUSINGWM_CONCAT_IMPL;

d、创建同义词并授权

createpublicsynonymWM_CONCAT_IMPLforsys.WM_CONCAT_IMPLcreatepublicsynonymwm_concatforsys.wm_concatgrantexecuteonWM_CONCAT_IMPLtopublicgrantexecuteonwm_concattopublic

然后查看function状态,正常状态。至此问题解决。

总结

1、从网上找资料了解到,11gr2和12C上已经摒弃了wm_concat函数,而应用在程序中确使用了该函数,导致程序出现错误,为了减轻程序员修改程序的工作量,只有通过手工创建个wm_concat函数,来临时解决该问题,但是注意,及时创建了该函数,在使用的过程中,也需要用to_char(wm_concat())方式,才能完全替代之前的应用。

2、也查到了说VMSYS用户下有该函数,但是默认该用户是锁定的,此次问题我也解锁了VMSYS用户,但是并无该function

SQL>alteruserWMSYSaccountunlock;Useraltered.SQL>selectowner,object_name,object_typefromdba_objectswhereowner='WMSYS'andobject_type='FUNCTION';norowsselected

3、手工重建,保留脚本以后出现类似问题可以很快速重建。

更多相关内容:

ORA-00911: 无效字符问题案例以及解决方法

oracle监听器启动1067错误处理的方法