在 Oracle 领域,我相信一说到列转行大部分人都会立马想到 WM_CONCAT 函数,我觉得主要是因为该函数比较实用。但事实上 WM_CONCAT 并非官方公开函数,使用会存在一定的风险;函数返回值的格式比较单一(只能用逗号分割);返回值的长度也限制。

《.Net程序员学用Oracle系列(20):层次查询(CONNECT BY)》一文中,详细讲解了 WM_CONCAT 函数的用法。如果不用 WM_CONCAT 函数又该如何实现列转行呢?当数据类别比较少的时候,通过 CASE 判断或 UNION ALL 查询也能实现效果,但问题就是写法太死板,不过一般也没人会这么干。本文接下来会介绍两个自定义函数分别来实现列转行的聚合效果。

第一个自定义函数主要是辅以 COLLECT 函数来实现的,我在回答一个园友的问题时列出了实现步骤,查看该问题。下面是我重新整理后的版本:

第 1 步(创建类型 type_table_string,用于转换 COLLECT 函数的返回值):

CREATE OR REPLACE TYPE type_table_string IS TABLE OF VARCHAR2(4000);

第 2 步(创建函数 fn_to_string,用于将 type_table_string 类型转换成普通字符串):

CREATE OR REPLACE FUNCTION fn_to_string(
p_str_tab IN type_table_string,
p_separator IN VARCHAR2 DEFAULT ','
)
RETURN VARCHAR2 IS
v_ret_str VARCHAR2(4000);
BEGIN
FOR i IN 1..p_str_tab.COUNT LOOP
v_ret_str:=v_ret_str||p_separator||p_str_tab(i);
END LOOP;
RETURN LTRIM(v_ret_str,p_separator);
END;

调用方法:

SELECT t.dept_code,fn_to_string(CAST(COLLECT(t.staff_name) AS type_table_string),'|') staff_names
FROM demo.t_staff t GROUP BY t.dept_code;

调用结果:

DEPT_CODE                        STAFF_NAMES
-------------------------------- ----------------------------------------------
010101 小明|小强|王二
010102 小林|小萨
010103 韩三|小玲
010104 小梅|小燕
010201 小军|小芳|小红
010202 小飞

第二个自定义函数在百度中输入“zh_concat”就能找到一堆的参考,我有尝试寻找 zh_concat 函数的出处,但网上的翻版实在太多,而且大部分比较无耻(没写出处),结果就是我没能找到该函数的出处,因此在这里我也没法儿给出 zh_concat 函数的出处了。

我找到的那些有关 zh_concat 函数的帖子内容普遍比较混乱,于是我决定整理出一个更加清晰、整洁和美观的版本,以便阅读和理解,具体如下:

第 1 步(创建类型 type_concat 的定义):

CREATE OR REPLACE TYPE type_concat
AUTHID CURRENT_USER AS OBJECT(
v_result_string VARCHAR2(4000),
STATIC FUNCTION odciAggregateInitialize(
concat IN OUT type_concat) RETURN NUMBER,
MEMBER FUNCTION odciAggregateIterate(
SELF IN OUT type_concat,str IN VARCHAR2) RETURN NUMBER,
MEMBER FUNCTION odciAggregateTerminate(
SELF IN type_concat,return_value OUT VARCHAR2,flags IN NUMBER) RETURN NUMBER,
MEMBER FUNCTION odciAggregateMerge(
SELF IN OUT type_concat,concat IN type_concat) RETURN NUMBER
);

第 2 步(创建类型 type_concat 的 body):

CREATE OR REPLACE TYPE BODY type_concat
IS
STATIC FUNCTION odciAggregateInitialize(concat IN OUT type_concat)
RETURN NUMBER IS
BEGIN
concat := type_concat(NULL);
RETURN ODCICONST.SUCCESS;
END; MEMBER FUNCTION odciAggregateIterate(SELF IN OUT type_concat,str IN VARCHAR2)
RETURN NUMBER IS
BEGIN
IF SELF.v_result_string IS NOT NULL THEN
SELF.v_result_string := SELF.v_result_string||','||str;
ELSE
SELF.v_result_string := str;
END IF;
RETURN ODCICONST.SUCCESS;
END; MEMBER FUNCTION odciAggregateTerminate(SELF IN type_concat,return_value OUT VARCHAR2,flags IN NUMBER)
RETURN NUMBER IS
BEGIN
return_value := SELF.v_result_string;
RETURN ODCICONST.SUCCESS;
END; MEMBER FUNCTION odciAggregateMerge(SELF IN OUT type_concat,concat IN type_concat)
RETURN NUMBER IS
BEGIN
IF concat.v_result_string IS NOT NULL THEN
SELF.v_result_string := SELF.v_result_string||','||concat.v_result_string;
END IF;
RETURN ODCICONST.SUCCESS;
END;
END;

第 3 步(创建函数 fn_concat,可替代 WM_CONCAT):

CREATE OR REPLACE FUNCTION fn_concat(str VARCHAR2)
RETURN VARCHAR2 AGGREGATE USING type_concat;

调用方法:

SELECT t.dept_code,fn_concat(t.staff_name) staff_names FROM demo.t_staff t GROUP BY t.dept_code;

调用结果:

DEPT_CODE                             STAFF_NAMES
------------------------------------- ----------------------------------------------------
010101 小明,小强,王二
010102 小林,小萨
010103 韩三,小玲
010104 小梅,小燕
010201 小军,小芳,小红
010202 小飞

说明一:上例中的 AUTHID CURRENT_USER 是权限控制的关键字,表示调用者权限,即当前用户。默认为 AUTHID DEFINER,表示定义者权限,即模式拥有者。

说明二:将 type_concat 中 v_result_string 和 return_value 的类型改为 CLOB 类型,并将 fn_concat 的返回值类型也改为 CLOB,就成了 CLOB 版的 fn_concat 了。

本文链接http://www.cnblogs.com/hanzongze/p/oracle-wm_concat.html

版权声明:本文为博客园博主 韩宗泽 原创,作者保留署名权!欢迎通过转载、演绎或其它传播方式来使用本文,但必须在明显位置给出作者署名和本文链接!个人博客,能力有限,若有不当之处,敬请批评指正,谢谢!

Oracle 自定义函数实现列转行效果的更多相关文章

  1. Mybatis下配置调用Oracle自定义函数返回的游标结果集

    在ibatis和Mybatis对存储过程和函数函数的调用的配置Xml是不一样的,以下是针对Mybatis 3.2的环境进行操作的. 第一步配置Mapper的xml内容 <mapper names ...

  2. 【转】Oracle 自定义函数语法与实例

    原文地址:https://blog.csdn.net/libertine1993/article/details/47264211 Oracle自定义函数的语法如下: create or replac ...

  3. Oracle自定义函数和存储过程示例,自定义函数与存储过程区别

    参考资料:http://www.newbooks.com.cn/info/60861.html oracle自定义函数学习和连接运算符(||) 贴一段中文文档示例,应该就可以开始工作了: --过程(P ...

  4. Oracle自定义行转列函数

    --行转列自定义函数,只针对TABLE1表 --paramType是参数类型,用于判断,param1和param2是条件参数 create or replace function My_concat( ...

  5. Oracle自定义函数1

    用户定义函数是存储在数据库中的代码块,可以把值返回到调用程序.调用时如同系统函数一样,如max(value)函数,其中,value被称为参数.函数参数有3种类型. IN 参数类型:表示输入给函数的参数 ...

  6. Oracle自定义函数

    核心提示:函数用于返回特定数据.执行时得找一个变量接收函数的返回值; 语法如下: create or replace function function_name ( argu1 [mode1] da ...

  7. Oracle自定义函数&加密

    在sql中频繁使用的功能(逻辑.加密等)可以写成自定义函数进行封装,之后再调用即可. CREATE OR REPLACE FUNCTION "函数名" (参数名 参数类型 参数数据 ...

  8. oracle自定义函数:将使用点分隔符的编码转成层级码格式的编码

    维护一个旧的系统,表设计中只有编码,而没有其他排序相关的字段,然后根据编码排序出现了顺序错乱的问题. 详细地说,其编码设计是使用[.]分隔符的编码,比如1.1.1.1.1.1.1.1.1.2这样的格式 ...

  9. oracle 逗号分割,列转行,行转列

    SQL代码 列转行 select REGEXP_SUBSTR(a.rolecode ,,l) rolecode from ( select 'a,aa,aaa' rolecode from dual ...

随机推荐

  1. WPF两个按钮来回切换样式

    <!-- 两个按钮来回切换样式 --> <Style x:Key="SwicthFunctionMetroToggleButton" TargetType=&qu ...

  2. C 预处理器、头文件、文件读写

    预处理器 参考链接:https://www.runoob.com/cprogramming/c-preprocessors.html 预处理器是再变异之前做的一些工作 include 包含一个源文件代 ...

  3. npm 查看全局安装模块

    方法一: npm list -g --depth 0 方法二: 输入npm root -g  得到全局node_modules的地址 在任意文件夹输入此地址,便可查看所安模块 https://blog ...

  4. JS实现16进制和RGB转换

    作为前端开发而言,不可避免的会遇到颜色取值,字符串和数字直接的转换,博主为此写了一个小工具,实现色值之间的在线转换. 前置知识点: parseInt, toString parseInt(value ...

  5. 【MySQL高可用架构设计】(一)-- mysql复制功能介绍

    一. 介绍 Mysql的复制功能是构建基于SQL数据库的大规模高性能应用的基础,主要用于分担主数据库的读负载,同时也为高可用.灾难恢复.备份等工作提供了更多的选择. 二.为什么要使用mysql复制功能 ...

  6. 3.3 Spark的部署和应用方式

    一.Spark的部署 1.单机Local 2.集群 (1)Standalonc Spark自带的资源管理器,效率不高 (2)YARN 如果部署的是Hadoop集群,可以用YARN资源调度 (3)Mes ...

  7. Codeforces Round #590 (Div. 3) F

    传送门 题意: 给出一个只含前\(20\)个字符的字符串,现在可以选择一段区间进行翻转,问区间中字符各不相同时,最长长度为多少. 思路: 首先,容易将题意转换为选择两个字符各不相同的区间,然后长度相加 ...

  8. 初识V4l2(二)-------浅析video_register_device

    在V4l2初识(一)中,我们已经知道当插上一个摄像头的时候,在uvc_driver.c中最终会调用函数video_register_device函数.接下来我们就简要分析这个函数做了哪些事情,揭开其神 ...

  9. LiunxCentos7 上安装 FastDFS

    Centos7 上安装 FastDFS 1.安装gcc(编译时需要) FastDFS是C语言开发,安装FastDFS需要先将官网下载的源码进行编译,编译依赖gcc环境,如果没有gcc环境,需要安装gc ...

  10. 搭建Dubbo Admin(五)

    Dubbo Admin下载地址(2019年9月8日):https://github.com/apache/dubbo-admin 注意:JDK要求1.8以上 1. 进入到模块 dubbo-admin- ...