stract oracle,Oracle聚集函数和分析函数

2023-05-16

Oracle的定制功能十分强大。前几天在碰到一个问题的时候,查询文档发现,oracle不但允许用户定制自己的函数,还可以定制自己的聚集函数和分析函数。

下面是我使用自定义聚集函数建立一个字符串“sum”的小例子。

SQL> CREATE OR REPLACE

TYPE T_LINK AS OBJECT (

2 STR VARCHAR2(30000),

3 STATIC FUNCTION ODCIAGGREGATEINITIALIZE(SCTX IN OUT T_LINK) RETURN

NUMBER,

4 MEMBER FUNCTION ODCIAGGREGATEITERATE(SELF IN OUT T_LINK, VALUE IN

VARCHAR2) RETURN NUMBER,

5 MEMBER FUNCTION ODCIAGGREGATETERMINATE(SELF IN T_LINK, RETURNVALUE

OUT VARCHAR2, FLAGS IN NUMBE

R) RETURN NUMBER,

6 MEMBER FUNCTION ODCIAGGREGATEMERGE(SELF IN OUT T_LINK, CTX2 IN

T_LINK) RETURN NUMBER

7 )

8 /

类型已创建。

SQL> CREATE OR REPLACE

TYPE BODY T_LINK IS

2 STATIC FUNCTION ODCIAGGREGATEINITIALIZE(SCTX IN OUT T_LINK) RETURN

NUMBER IS

3 BEGIN

4 SCTX := T_LINK(NULL);

5 RETURN ODCICONST.SUCCESS;

6 END;

7

8 MEMBER FUNCTION ODCIAGGREGATEITERATE(SELF IN OUT T_LINK, VALUE IN

VARCHAR2) RETURN NUMBER IS

9 BEGIN

10 SELF.STR := SELF.STR || VALUE;

11 RETURN ODCICONST.SUCCESS;

12 END;

13

14 MEMBER FUNCTION ODCIAGGREGATETERMINATE(SELF IN T_LINK, RETURNVALUE

OUT VARCHAR2, FLAGS IN NUMBE

R) RETURN NUMBER IS

15 BEGIN

16 RETURNVALUE := SELF.STR;

17 RETURN ODCICONST.SUCCESS;

18 END;

19

20 MEMBER FUNCTION ODCIAGGREGATEMERGE(SELF IN OUT T_LINK, CTX2 IN

T_LINK) RETURN NUMBER IS

21 BEGIN

22 NULL;

23 RETURN ODCICONST.SUCCESS;

24 END;

25 END;

26 /

类型主体已创建。

SQL> CREATE OR REPLACE

FUNCTION F_LINK(P_STR VARCHAR2) RETURN VARCHAR2

2 AGGREGATE USING T_LINK;

3 /

函数已创建。

SQL> CREATE TABLE TEST

(ID NUMBER, NAME VARCHAR2(20));

表已创建。

SQL> INSERT INTO TEST

VALUES (1, 'AAA');

已创建 1 行。

SQL> INSERT INTO TEST

VALUES (2, 'BBB');

已创建 1 行。

SQL> INSERT INTO TEST

VALUES (1, 'ABC');

已创建 1 行。

SQL> INSERT INTO TEST

VALUES (3, 'CCC');

已创建 1 行。

SQL> INSERT INTO TEST

VALUES (2, 'DDD');

已创建 1 行。

SQL> COMMIT;

提交完成。

SQL> COL NAME FORMAT

A60

SQL> SELECT ID,

F_LINK(NAME) NAME FROM TEST GROUP BY ID;

ID NAME

----------

------------------------------------------------------

1 AAAABC

2 BBBDDD

3 CCC

另外:

oracle自定义聚集函数接口简介

a.

static function ODCIAggregateInitialize(sctx IN OUTstring_agg_type

)

return

number

自定义聚集函数初始化设置,从这儿开始一个聚集函数

b.

member function ODCIAggregateIterate(self IN OUT string_agg_type

,value IN varchar2)

return

number

自定义聚集函数,最主要的步骤,这个函数定义我们的聚集函数具体做什么操作,后面的例子,是取最大值,最小值,平均值,还是做连接操作.self

为当前聚集函数的指针,用来与前面的计算结果进行关联

c.

member function ODCIAggregateMerge (self IN

string_agg_type,returnValue

OUT varchar2,flags IN

number)

return

number

用来合并两个聚集函数的两个不同的指针对应的结果,用户合并不同结果结的数据,特别是处理并行(parallel)查询聚集函数的时候.

d. member function OCDIAggregateTerminate(self IN

string_agg_type,returnValue OUT varchar2,flags IN number)

终止聚集函数的处理,返回聚集函数处理的结果.

2. 实现的例子.

[code]

create type strcat_type as object (

cat_string varchar2(4000),

static function ODCIAggregateInitialize(cs_ctx In Out strcat_type)

return number,

member function ODCIAggregateIterate(self In Out strcat_type,value

in varchar2) return number,

member function ODCIAggregateMerge(self In Out strcat_type,ctx2 In

Out strcat_type) return number,

member function ODCIAggregateTerminate(self In Out

strcat_type,returnValue Out varchar2,flags in number) return

number

)

/

create type body strcat_type is

static function

ODCIAggregateInitialize(cs_ctx IN OUT strcat_type) return

number

is

begin

cs_ctx :=

strcat_type( null );

return

ODCIConst.Success;

end;

member function

ODCIAggregateIterate(self IN OUT strcat_type,

value IN

varchar2 )

return number

is

begin

self.cat_string := self.cat_string || ','||

value;

return

ODCIConst.Success;

end;

member function

ODCIAggregateTerminate(self IN Out strcat_type,

returnValue

OUT varchar2,

flags IN

number)

return number

is

begin

returnValue

:= ltrim(rtrim(self.cat_string,','),',');

return

ODCIConst.Success;

end;

member function

ODCIAggregateMerge(self IN OUT strcat_type,

ctx2 IN Out

strcat_type)

return number

is

begin

self.cat_string := self.cat_string || ',' ||

ctx2.cat_string;

return

ODCIConst.Success;

end;

end;

/

CREATE or replace

FUNCTION strcat(input varchar2 )

RETURN varchar2

PARALLEL_ENABLE AGGREGATE USING

strcat_type;

/

[/code]

3. 具体应用,

[code]

15:16:52 SQL> select

empno,ename,deptno,job from scott.emp;

EMPNO

ENAME DEPTNO

JOB

---------- ---------- ----------

---------

7369

SMITH 20 CLERK

7499

ALLEN 30

SALESMAN

7521

WARD 30

SALESMAN

7566

JONES 20

MANAGER

7654

MARTIN 30

SALESMAN

7698

BLAKE 30

MANAGER

7782

CLARK 10

MANAGER

7788

SCOTT 20

ANALYST

7839

KING 10

PRESIDENT

7844

TURNER 30

SALESMAN

7876

ADAMS 20 CLERK

7900

JAMES 30 CLERK

7902

FORD 20

ANALYST

7934

MILLER 10

CLERK

14 rows selected.

Elapsed: 00:00:00.01

15:18:29 SQL> col

dept_emplist format a60

15:18:41 SQL> select

deptno,strcat(empno||'-'||ename) dept_emplist

15:19:01 2 from

scott.emp group by deptno;

DEPTNO DEPT_EMPLIST

----------

------------------------------------------------------------

10

7782-CLARK,7839-KING,7934-MILLER

20

7369-SMITH,7902-FORD,7876-ADAMS,7788-SCOTT,7566-JONES

30

7499-ALLEN,7698-BLAKE,7654-MARTIN,7844-TURNER,7900-JAMES,7521-WARD

Elapsed: 00:00:00.04

15:19:08 SQL> col

job_emplist format a80

15:19:23 SQL> select

job,strcat(empno||'-'||ename) job_emplist

15:19:43 2 from

scott.emp group by job;

JOB JOB_EMPLIST

---------

--------------------------------------------------------------------------------

ANALYST 7788-SCOTT,7902-FORD

CLERK 7369-SMITH,7900-JAMES,7876-ADAMS,7934-MILLER

MANAGER 7566-JONES,7782-CLARK,7698-BLAKE

PRESIDENT 7839-KING

SALESMAN 7499-ALLEN,7521-WARD,7844-TURNER,7654-MARTIN

Elapsed: 00:00:00.03

15:19:50 SQL>

[/code]

字符串聚合

===========================================================

作者:

jackywood(http://jackywood.itpub.net)

发表于: 2006.07.01 00:33

分类: 技术探讨

出处:

http://jackywood.itpub.net/post/1369/129288

---------------------------------------------------------------

在put上经常见到有人问"字符串连接"或是"一列多行数据怎么变为一列一行",

在此汇总我所知比较好的几种字符串聚合的方法,

供大家参考.

在这里生成测试数据, 后面详细介绍方法的时候需要用到.

create table tb_agg(

val varchar2(4),

gcol varchar2(4)

)

/

insert into tb_agg

select lpad(rownum,2,'0'), ceil(rownum/5) from dual connect by rownum<=20;

commit;

1. 通过 sys_connect_by_path

需要对数据进行树型构造, 在通过sys_connect_by_path完成字符串的的聚合.

这种方法便于对聚合元素排序, 但是元素与元素间必须要有分割符(如不需要分割符, 需要最后replace掉), 且聚合后的数据不能超过varchar2最大长度的限制.

示例: (该方法中需要用到分析函数来构造树型结构, 并用connect by进行查询)

SQL> with t as (

2 select val, gcol,

3 lag(val) over(partition by gcol order by val) as pval1

4 from tb_agg

5 )

6 select gcol, max(sys_connect_by_path(val, '/')) as aggr

7 from t

8 start with pval1 is null

9 connect by prior val=pval1

10 group by gcol

11 /

GCOL AGGR

-------- ----------------------------------------

1 /01/02/03/04/05

2 /06/07/08/09/10

3 /11/12/13/14/15

4 /16/17/18/19/20

2. 通过自定义聚合函数完成

需要用到oracle提供的自定义聚合函数的方法, 先定义聚合type, 然后定义函数, 来完成字符串的聚合.

这种方法可以任意指定分割符或无分割符, 聚合长度可以通过根据type中定义的不同, 返回varchar2或clob, 因此可以不受varchar2上限限制, 但是对聚合元素排序的话需要特殊处理.

3. 通过自定义集合实现

需要自定义集合类型, 并定义集合聚合函数.

这种方法的特定和自定义聚合函数基本类似.

详细参见: 字符串聚合之自定义集合

-- 注意声明时的长度, 合适的长度最佳, 不要过长, 也不要过小

create or replace type vars is table of varchar2(1000)

/

-- 返回为varchar2, 有 varchar2 大小上限限制的

create or replace function sumvar (p_in in vars) return varchar2

is

v_out varchar2(4000);

begin

for i in 1..p_in.count loop

v_out := v_out || p_in(i);

end loop;

return v_out;

end;

/

-- 返回clob, 无varchar2上限限制

create or replace function sumvarc (p_in in vars) return clob

is

v_out clob;

begin

for i in 1..p_in.count loop

v_out := v_out || p_in(i);

end loop;

return v_out;

end;

/

函数的使用示例:

SQL> select gcol,

2 sumvar(cast(multiset(select '/'||val

3 from tb_agg

4 where a.gcol=gcol

5 order by val) as vars

6 )

7 ) as aggr

8 from tb_agg a

9 group by gcol

10 /

GCOL AGGR

-------- ----------------------------------------

1 /01/02/03/04/05

2 /06/07/08/09/10

3 /11/12/13/14/15

4 /16/17/18/19/20

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

stract oracle,Oracle聚集函数和分析函数 的相关文章

  • 物化视图提交时快速刷新

    我刚刚创建了表 DEPT 和 EMP 如下所示 create table DEPT dept no number dept name varchar 32 dept desc varchar 32 CONSTRAINT dept pk Pr
  • BI Publisher 和 Excel 模板预览错误

    我正在使用 Excel 2013 并添加了 BI 发布器 我加载示例数据 并进行预览 我得到以下内容 请指教 谢谢詹姆斯 启动 Excel 预览 仅开放 false mTemplate C Users AJCENTROID AppData
  • 从 SQL 表在 SQL 中创建数据透视视图

    我有下表TEMP 我想使用 SQL 创建一个数据透视视图 排序依据CATEGORYASC 通过LEVEL降序和SETASC 并填写value 预期输出 我已尝试以下代码 但无法解决引发错误的聚合部分 SELECT FROM SELECT S
  • 超时后如何重新建立 JDBC 连接?

    我有一个长时间运行的方法 它通过 EntityManager TopLink Essentials 执行大量本机 SQL 查询 每个查询只需要几毫秒即可运行 但查询数量却有数千个 这发生在单个 EJB 事务内 15 分钟后 数据库关闭连接
  • 如何使用 JDBC 将大型(或至少是重要的)BLOB 放入 Oracle 中?

    我正在开发一个应用程序来执行一些批处理 并且希望将输入和输出数据作为文件存储在 Oracle 数据库的 BLOB 字段中 Oracle版本是10g r2 使用如下的PreparedStatement setBinaryStream 方法会将
  • 包括 Oracle 中的等效项

    在 SQL Server 中你可以这样写 create index indx on T1 A B INCLUDE C D E 有没有办法在 Oracle 中做同样的事情 Refs http msdn microsoft com en us
  • 从 Oracle Forms 调用 Microsoft Word 拼写检查时出现 Vista 焦点问题

    朋友们 在 Vista 上测试我们的 Oracle Forms 应用程序时 我发现了一个有趣的 挑战 应用程序可以调用 Microsoft Word 拼写检查器对字段执行拼写检查 调用时 用户将看到标准的 Microsoft Word 拼写
  • 什么时候空值在列中“安全”?

    设计数据库时是否存在允许列为空与 3nf 规范化的一般经验法则 我有一个表 其中的列主要由空值 85 组成 但表大小不超过 10K 记录 不是很大 它主要用于日志记录和记录保存 因此大多数事务将是插入和选择 而不是更新 我试图同时考虑性能和
  • 如何关闭 Oracle 密码过期功能?

    我正在使用 Oracle 进行开发 我经常用于重建数据库的引导帐户的密码已过期 如何永久关闭该用户 以及所有其他用户 的密码过期功能 我使用的是 Oracle 11g 默认情况下密码会过期 要更改 Oracle 中某个用户配置文件的密码过期
  • 在Oracle中,是否可以将以逗号分隔的非常大的字符串(clob)转换为具有更好性能的表

    我需要通过逗号分隔符将非常大的 clob 字符串转换为表 下面的函数需要很长时间 有没有返回表的快速函数 create or replace FUNCTION UDF STRSPLIT2 P STR IN CLOB P DELIM IN V
  • 从有序结果集中查找“运行”行

    我试图找出一种方法来识别满足某些条件的 运行 结果 按顺序连续行 目前 我正在订购结果集 并通过眼睛扫描特定模式 这是一个例子 SELECT the date name FROM orders WHERE the date BETWEEN
  • PL/SQL:如何声明会话变量?

    如何在 PL SQL 中声明一个会话变量 该变量仅在会话期间持续存在 而无需将其存储在数据库本身中 您可以使用 用户创建的上下文 来存储会话中多个单元共享的数据 首先 创建一个上下文 CREATE CONTEXT SYS CONTEXT u
  • Oracle PL/SQL - NO_DATA_FOUND 异常是否对存储过程性能不利?

    我正在编写一个需要进行大量调节的存储过程 根据 C NET 编码中的常识 异常会损害性能 因此我也始终避免在 PL SQL 中使用它们 我在此存储过程中的调节主要围绕记录是否存在 我可以通过以下两种方式之一进行 SELECT COUNT I
  • 如何使用 Hibernate 3.3.2GA 将 TIMESTAMP WITH TIME ZONE 映射到 Java 数据类型?

    如何映射 Oracle 列类型TIMESTAMP WITH TIME ZONE http download oracle com docs cd B19306 01 server 102 b14225 ch4datetime htm i10
  • 在oracle sql中创建日期差异的自定义函数,排除周末和节假日

    我需要计算两个日期之间的天数decimal 不包括周末和节假日 by 使用自定义函数在 Oracle SQL 中 网站上也有类似的问题 然而 正如我所看到的 它们都没有要求使用自定义函数将输出作为十进制 我需要小数的原因是为了之后能够使用
  • 如何为 Weblogic 10.3.6 启用 Java 持久性 2.0

    我正在使用 eclipse 和 weblogic 服务器 为了将项目添加到 weblogic 服务器 它需要支持 Java Persistance 2 0 但是当尝试安装它时 我不断收到此消息 在 Weblogic Server 安装中启用
  • 神秘的 getClobVal()

    我有一个表 AKADMIN 其中包含 XMLTYPE 列 其名称为 XML 我想在该列中使用 getClobVal select t xml getClobVal t xml getClobVal t xml getClobVal as c
  • oracle中是否有相当于concat_ws的东西?

    我有大量的列试图聚合在一起 其中大多数都有 NULL 值 我想分隔确实以 出现的值但我在oracle中找不到有效的方法来做到这一点 CONCAT WS 正是我所需要的 因为它不会在 NULL 值之间添加分隔符 但 Oracle 不支持这一点
  • 仅使用 SQL 中的 MAX 函数更新重复行

    我有一张这样的桌子 假设为了举例 NAME是一个唯一的标识符 NAME AGE VALUE Jack Under 65 3 Jack 66 74 5 John 66 74 7 John Over 75 9 Gill 25 35 11 Som
  • Oracle Many OR 与 IN () 的 SQL 性能调优 [重复]

    这个问题在这里已经有答案了 我手头没有 解释计划 您能帮忙判断以下哪一个更有效吗 选项1 select from VIEW ABC where STRING COL AA OR STRING COL BB OR STRING COL BB

随机推荐