Oracle内部函数 wmsys.wm_concat 替换办法及思考
2014-09-20 17:54
585 查看
如果你不知道这个函数没有关系,因为您可以有其他的办法来实现。如果你已经在使用这个函数,一定要注意。
wmsys.wm_concat 是ORACLE内部函数,没有对外公布,也就是说,你可以使用,但是如果发生什么问题ORACLE概不负责。最显然的是ORACLE版本从10.2.0.4 =》10.2.0.5 只是一个小版本的变更,足以让你的系统出现问题。当然,你可以选择不升级数据库版本。
那么有没有办法实现替换呢?答案当然是有的,使用自定义聚合函数或更换到Oracle 11g Release 2(此版本引入了LISTAGG 函数,使得聚集连接字符串变得很容易。并且允许使用我们指定连接串中的字段顺序)。现在我们在不改变版本的基础上,自己实现一个替换吧,ORACLE文档上就有现成的例子。直接修改一下就OK了。
由于聚合函数只支持一个参数,如果像我们现在这样实现的话,不能像LISTAGG一样,使用动态字符连接,比如| + =等自定义符号。
不过,这里也给了我们一上思考,可以定义一下Type,然后传入就可以了。如下。
首先创建一个类型。然后修改相应的传入参数便可,请参照下面蓝色(普通类型)与红色(自定义类型)对比,当然,你可以更深的扩展,以便完成更复杂的功能。
create or replace type ConcatObj as object(
fieldValue varchar2(1024),
separator varchar2(100)
)
Implement the type ConcatStrImpl to contain the
Implement the type body for
Create the user-defined aggregate:
Use
Oracle相关文档,链接地址:http://docs.oracle.com/cd/B19306_01/appdev.102/b14289/dciaggfns.htm
其他:
替代Oracle函数wmsys_wm_concat()函数
1.
create or replace function postgresql(p_tname varchar2, p_colname varchar2)
return clob is
v_tmp varchar2(200);
v_result clob;
v_cum sys_refcursor;
begin
open v_cum for 'select ' || p_colname || ' from ' || p_tname;
loop
fetch v_cum
into v_tmp;
exit when v_cum%notfound;
v_result := v_result || v_tmp;
end loop;
dbms_output.put_line(v_result);
return v_result;
end;
select postgresql('emp','ename') from dual
2.sys_connect_by_path
3.create or replace TYPE zh_concat_im
AUTHID CURRENT_USER AS OBJECT
(
CURR_STR VARCHAR2(32767),
STATIC FUNCTION ODCIAGGREGATEINITIALIZE(SCTX IN OUT zh_concat_im) RETURN NUMBER,
MEMBER FUNCTION ODCIAGGREGATEITERATE(SELF IN OUT zh_concat_im,
P1 IN VARCHAR2) RETURN NUMBER,
MEMBER FUNCTION ODCIAGGREGATETERMINATE(SELF IN zh_concat_im,
RETURNVALUE OUT VARCHAR2,
FLAGS IN NUMBER)
RETURN NUMBER,
MEMBER FUNCTION ODCIAGGREGATEMERGE(SELF IN OUT zh_concat_im,
SCTX2 IN zh_concat_im) RETURN NUMBER
);
/
create or replace TYPE BODY zh_concat_im
IS
STATIC FUNCTION ODCIAGGREGATEINITIALIZE(SCTX IN OUT zh_concat_im)
RETURN NUMBER
IS
BEGIN
SCTX := zh_concat_im(NULL) ;
RETURN ODCICONST.SUCCESS;
END;
MEMBER FUNCTION ODCIAGGREGATEITERATE(SELF IN OUT zh_concat_im,
P1 IN VARCHAR2)
RETURN NUMBER
IS
BEGIN
IF(CURR_STR IS NOT NULL) THEN
CURR_STR := CURR_STR || ':' || P1;
ELSE
CURR_STR := P1;
END IF;
RETURN ODCICONST.SUCCESS;
END;
MEMBER FUNCTION ODCIAGGREGATETERMINATE(SELF IN zh_concat_im,
RETURNVALUE OUT VARCHAR2,
FLAGS IN NUMBER)
RETURN NUMBER
IS
BEGIN
RETURNVALUE := CURR_STR ;
RETURN ODCICONST.SUCCESS;
END;
MEMBER FUNCTION ODCIAGGREGATEMERGE(SELF IN OUT zh_concat_im,
SCTX2 IN zh_concat_im)
RETURN NUMBER
IS
BEGIN
IF(SCTX2.CURR_STR IS NOT NULL) THEN
SELF.CURR_STR := SELF.CURR_STR || ':' || SCTX2.CURR_STR ;
END IF;
RETURN ODCICONST.SUCCESS;
END;
END;
/
函数:
create or replace FUNCTION zh_concat(P1 VARCHAR2)
RETURN VARCHAR2 AGGREGATE USING zh_concat_im ;
修改标红部门,可调整字段间分隔符
wmsys.wm_concat 是ORACLE内部函数,没有对外公布,也就是说,你可以使用,但是如果发生什么问题ORACLE概不负责。最显然的是ORACLE版本从10.2.0.4 =》10.2.0.5 只是一个小版本的变更,足以让你的系统出现问题。当然,你可以选择不升级数据库版本。
那么有没有办法实现替换呢?答案当然是有的,使用自定义聚合函数或更换到Oracle 11g Release 2(此版本引入了LISTAGG 函数,使得聚集连接字符串变得很容易。并且允许使用我们指定连接串中的字段顺序)。现在我们在不改变版本的基础上,自己实现一个替换吧,ORACLE文档上就有现成的例子。直接修改一下就OK了。
由于聚合函数只支持一个参数,如果像我们现在这样实现的话,不能像LISTAGG一样,使用动态字符连接,比如| + =等自定义符号。
不过,这里也给了我们一上思考,可以定义一下Type,然后传入就可以了。如下。
首先创建一个类型。然后修改相应的传入参数便可,请参照下面蓝色(普通类型)与红色(自定义类型)对比,当然,你可以更深的扩展,以便完成更复杂的功能。
create or replace type ConcatObj as object(
fieldValue varchar2(1024),
separator varchar2(100)
)
Implement the type ConcatStrImpl to contain the
ODCIAggregateroutines:
create type ConcatStrImpl as object ( default_str varchar2(32767), -- 也只能这么大,再大就越界了 sep varchar2(100), --定义分隔符,以便以后使用 static function ODCIAggregateInitialize(sctx IN OUT ConcatStrImpl) return number, member function ODCIAggregateIterate(self IN OUT ConcatStrImpl, value IN varchar2) return number, member function ODCIAggregateIterate(self IN OUT ConcatStrImpl, value IN ConcatObj) return number, member function ODCIAggregateTerminate(self IN ConcatStrImpl, returnValue OUT varchar2, flags IN number) return number, member function ODCIAggregateMerge(self IN OUT ConcatStrImpl, ctx2 IN ConcatStrImpl) return number );
Implement the type body for
ConcatStrImpl:
create or replace type body ConcatStrImpl is static function ODCIAggregateInitialize(sctx IN OUT ConcatStrImpl) return number is begin sctx:= ConcatStrImpl(null); sctx:= ConcatStrImpl(null,null); return ODCIConst.Success; end; member function ODCIAggregateIterate(self IN OUT ConcatStrImpl, value IN varchar2) return number is begin if self.default_str is not null then self.default_str := self.default_str || ',' || value; -- 逗号分隔 else self.default_str:= value; end if; return ODCIConst.Success; end; member function ODCIAggregateIterate(self IN OUT ConcatStrImpl, value IN ConcatObj) return number is begin if self.default_str is not null and value.fieldValue is not null then self.default_str := self.default_str || self.sep|| value.fieldValue; elsif value.fieldValue is not null then self.default_str:= value.fieldValue; self.sep:= value.separator; end if; return ODCIConst.Success; end; member function ODCIAggregateTerminate(self IN ConcatStrImpl, returnValue OUT varchar2, flags IN number) return number is begin returnValue := self.default_str; return ODCIConst.Success; end; member function ODCIAggregateMerge(self IN OUT ConcatStrImpl, ctx2 IN ConcatStrImpl) return number is begin if ctx2.default_str is not null then self.default_str := self.default_str || ',' ||ctx2.default_str; end if; return ODCIConst.Success; end; member function ODCIAggregateMerge(self IN OUT ConcatStrImpl, ctx2 IN ConcatStrImpl) return number is begin if ctx2.default_str is not null and self.default_str is not null then self.default_str := self.default_str || self.sep||ctx2.default_str; elsif ctx2.default_str is not null then self.default_str := ctx2.default_str; end if; return ODCIConst.Success; end; end;
Create the user-defined aggregate:
CREATE FUNCTION ConcatStr (input varchar2) RETURN varchar2 PARALLEL_ENABLE AGGREGATE USING ConcatStrImpl; CREATE FUNCTION ConcatStr1 (input ConcatObj) RETURN varchar2 PARALLEL_ENABLE AGGREGATE USING ConcatStrImpl1;
Use
ConcatStr():
SELECT ConcatStr(salary), department_id FROM employees; SELECT ConcatStr1(ConcatObj(salary,'=')), department_id FROM employees;
Oracle相关文档,链接地址:http://docs.oracle.com/cd/B19306_01/appdev.102/b14289/dciaggfns.htm
其他:
替代Oracle函数wmsys_wm_concat()函数
1.
create or replace function postgresql(p_tname varchar2, p_colname varchar2)
return clob is
v_tmp varchar2(200);
v_result clob;
v_cum sys_refcursor;
begin
open v_cum for 'select ' || p_colname || ' from ' || p_tname;
loop
fetch v_cum
into v_tmp;
exit when v_cum%notfound;
v_result := v_result || v_tmp;
end loop;
dbms_output.put_line(v_result);
return v_result;
end;
select postgresql('emp','ename') from dual
2.sys_connect_by_path
3.create or replace TYPE zh_concat_im
AUTHID CURRENT_USER AS OBJECT
(
CURR_STR VARCHAR2(32767),
STATIC FUNCTION ODCIAGGREGATEINITIALIZE(SCTX IN OUT zh_concat_im) RETURN NUMBER,
MEMBER FUNCTION ODCIAGGREGATEITERATE(SELF IN OUT zh_concat_im,
P1 IN VARCHAR2) RETURN NUMBER,
MEMBER FUNCTION ODCIAGGREGATETERMINATE(SELF IN zh_concat_im,
RETURNVALUE OUT VARCHAR2,
FLAGS IN NUMBER)
RETURN NUMBER,
MEMBER FUNCTION ODCIAGGREGATEMERGE(SELF IN OUT zh_concat_im,
SCTX2 IN zh_concat_im) RETURN NUMBER
);
/
create or replace TYPE BODY zh_concat_im
IS
STATIC FUNCTION ODCIAGGREGATEINITIALIZE(SCTX IN OUT zh_concat_im)
RETURN NUMBER
IS
BEGIN
SCTX := zh_concat_im(NULL) ;
RETURN ODCICONST.SUCCESS;
END;
MEMBER FUNCTION ODCIAGGREGATEITERATE(SELF IN OUT zh_concat_im,
P1 IN VARCHAR2)
RETURN NUMBER
IS
BEGIN
IF(CURR_STR IS NOT NULL) THEN
CURR_STR := CURR_STR || ':' || P1;
ELSE
CURR_STR := P1;
END IF;
RETURN ODCICONST.SUCCESS;
END;
MEMBER FUNCTION ODCIAGGREGATETERMINATE(SELF IN zh_concat_im,
RETURNVALUE OUT VARCHAR2,
FLAGS IN NUMBER)
RETURN NUMBER
IS
BEGIN
RETURNVALUE := CURR_STR ;
RETURN ODCICONST.SUCCESS;
END;
MEMBER FUNCTION ODCIAGGREGATEMERGE(SELF IN OUT zh_concat_im,
SCTX2 IN zh_concat_im)
RETURN NUMBER
IS
BEGIN
IF(SCTX2.CURR_STR IS NOT NULL) THEN
SELF.CURR_STR := SELF.CURR_STR || ':' || SCTX2.CURR_STR ;
END IF;
RETURN ODCICONST.SUCCESS;
END;
END;
/
函数:
create or replace FUNCTION zh_concat(P1 VARCHAR2)
RETURN VARCHAR2 AGGREGATE USING zh_concat_im ;
修改标红部门,可调整字段间分隔符
相关文章推荐
- oracle 内部函数 wmsys.wm_concat
- oracle 替换wmsys.wm_concat的函数
- oracle 函数WMSYS.WM_CONCAT()的用法(行转列)
- Oracle: wmsys.wm_concat、sys_connect_by_path、自定义函数实现行列转换
- Oracle 函数 wmsys.wm_concat 的几个用法
- 关于ORACLE wmsys.wm_concat 行转列函数使用
- oracle分析函数:四、listagg和wmsys.wm_concat
- Oracle: wmsys.wm_concat、sys_connect_by_path、自定义函数实现行列转换
- ORACLE wmsys.wm_concat()函数把某列数据整合到一起
- Oracle多行转一行:wmsys.wm_concat、sys_connect_by_path、自定义函数实现行列转换
- oracle 函数 WMSYS.WM_CONCAT 的用法 与 mysql 函数GROUP_CONCAT的用法
- 初学Oracle UNPIVOT,PIVOT,WMSYS.WM_CONCAT三个函数
- oracle 函数 WMSYS.WM_CONCAT 的用法 与 mysql 函数GROUP_CONCAT的用法
- oracle中的wmsys.wm_concat()函数
- Oracle List 功能 《=》 Oracle: wmsys.wm_concat、sys_connect_by_path、自定义函数实现行列转换
- oracle 函数 WMSYS.WM_CONCAT 与对应 mysql 函数GROUP_CONCAT的用法
- oracle 列转行函数 WMSYS.WM_CONCAT 排序不规则处理
- oracle 函数 WMSYS.WM_CONCAT 的用法 与 mysql 函数GROUP_CONCAT的用法
- ORACLE wm_concat (wmsys.) 函数(行列转换函数)
- oracle 函数 WMSYS.WM_CONCAT 的用法 与 mysql 函数GROUP_CONCAT的用法