日期:2014-05-16  浏览次数:20684 次

自定义聚合函数以及字符串连接超长的解决

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

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

类型声明:
CREATE OR REPLACE TYPE SUM_LINK AS OBJECT (
? STR VARCHAR2(30000),
? STATIC FUNCTION ODCIAGGREGATEINITIALIZE(SCTX IN OUT SUM_LINK) RETURN NUMBER,
? MEMBER FUNCTION ODCIAGGREGATEITERATE(SELF IN OUT SUM_LINK, VALUE IN VARCHAR2) RETURN NUMBER,
? MEMBER FUNCTION ODCIAGGREGATETERMINATE(SELF IN SUM_LINK, RETURNVALUE OUT VARCHAR2, FLAGS IN NUMBER) RETURN NUMBER,
? MEMBER FUNCTION ODCIAGGREGATEMERGE(SELF IN OUT SUM_LINK, CTX2 IN SUM_LINK) RETURN NUMBER
? )

类型主体:
?
CREATE OR REPLACE TYPE BODY SUM_LINK IS
? STATIC FUNCTION ODCIAGGREGATEINITIALIZE(SCTX IN OUT SUM_LINK) RETURN NUMBER IS
? BEGIN
? SCTX := SUM_LINK(NULL);
? RETURN ODCICONST.SUCCESS;
? END;

? MEMBER FUNCTION ODCIAGGREGATEITERATE(SELF IN OUT SUM_LINK, VALUE IN VARCHAR2) RETURN NUMBER IS
? BEGIN
?SELF.STR := SELF.STR || VALUE||';';
?RETURN ODCICONST.SUCCESS;
?END;

?MEMBER FUNCTION ODCIAGGREGATETERMINATE(SELF IN SUM_LINK, RETURNVALUE OUT VARCHAR2, FLAGS IN NUMBER) RETURN NUMBER IS
?BEGIN
? RETURNVALUE := SELF.STR;
?RETURN ODCICONST.SUCCESS;
?END;

?MEMBER FUNCTION ODCIAGGREGATEMERGE(SELF IN OUT SUM_LINK, CTX2 IN SUM_LINK) RETURN NUMBER IS
?BEGIN
? NULL;
? RETURN ODCICONST.SUCCESS;
? END;
? END;
?
?
方法创建:
?
CREATE OR REPLACE FUNCTION SUM_LINK(P_STR VARCHAR2) RETURN VARCHAR2
? AGGREGATE USING SUM_LINK;

?

? 建表、插入数据,用来测试:
??
CREATE TABLE TEST (ID NUMBER, NAME VARCHAR2(20));
?? INSERT INTO TEST VALUES (1, 'AAA');
?? INSERT INTO TEST VALUES (2, 'BBB');
?? INSERT INTO TEST VALUES (1, 'ABC');
?? INSERT INTO TEST VALUES (3, 'CCC');
?? INSERT INTO TEST VALUES (2, 'DDD');
?? COMMIT;

?

测试自定义函数和类型:
SQL> SELECT ID, SUM_LINK(NAME) NAME FROM TEST GROUP BY ID;

??????? ID?NAME
----------?----------------------------

???????? 1????? AAA;ABC;

???????? 2????? BBB;DDD;

???????? 3????? CCC;
?
这里介绍一下通过SQL的方法来解决同样的问题。

对于下面这个利用自定义聚集函数的例子,将其改写为直接用SQL实现:
SQL> SELECT * FROM TAB;
TNAME? TABTYPE? CLUSTERID
------ -------- ------------------------------------ ------- ----------
SY_NAME SYNONYM
T????? TABLE
TEST?? TABLE
TEST1? TABL