CREATETYPE LISTAGG_DISTINCT_PARAMSASOBJECT(ELEMENTO VARCHAR2(2000),SEPARATORE VARCHAR2(10));CREATETYPE T_LISTA_ELEMENTIASTABLEOFVARCHAR2(2000);CREATETYPE T_LISTAGG_DISTINCTASOBJECT(LISTA_ELEMENTI T_LISTA_ELEMENTI,SEPARATORE VARCHAR2(10),STATICFUNCTIONODCIAGGREGATEINITIALIZE(SCTXINOUT T_LISTAGG_DISTINCT)RETURNNUMBER,MEMBERFUNCTIONODCIAGGREGATEITERATE(SELFINOUT T_LISTAGG_DISTINCT,VALUEINLISTAGG_DISTINCT_PARAMS)RETURNNUMBER,MEMBERFUNCTIONODCIAGGREGATETERMINATE(SELFINT_LISTAGG_DISTINCT,RETURN_VALUE OUT VARCHAR2,FLAGSINNUMBER)RETURNNUMBER,MEMBERFUNCTIONODCIAGGREGATEMERGE(SELFINOUT T_LISTAGG_DISTINCT,CTX2INT_LISTAGG_DISTINCT)RETURNNUMBER);CREATEORREPLACE TYPE BODY T_LISTAGG_DISTINCTISSTATICFUNCTIONODCIAGGREGATEINITIALIZE(SCTXINOUT T_LISTAGG_DISTINCT)RETURNNUMBERISBEGINSCTX:=T_LISTAGG_DISTINCT(T_LISTA_ELEMENTI(),',');RETURNODCICONST.SUCCESS;END;MEMBERFUNCTIONODCIAGGREGATEITERATE(SELFINOUT T_LISTAGG_DISTINCT,VALUEINLISTAGG_DISTINCT_PARAMS)RETURNNUMBERISBEGINIFVALUE.ELEMENTOISNOTNULLTHENSELF.LISTA_ELEMENTI.EXTEND;SELF.LISTA_ELEMENTI(SELF.LISTA_ELEMENTI.LAST):=TO_CHAR(VALUE.ELEMENTO);SELF.LISTA_ELEMENTI:=SELF.LISTA_ELEMENTI MULTISETUNIONDISTINCTSELF.LISTA_ELEMENTI;SELF.SEPARATORE:=VALUE.SEPARATORE;ENDIF;RETURNODCICONST.SUCCESS;END;MEMBERFUNCTIONODCIAGGREGATETERMINATE(SELFINT_LISTAGG_DISTINCT,RETURN_VALUE OUT VARCHAR2,FLAGSINNUMBER)RETURNNUMBERISSTRINGA_OUTPUT CLOB:='';LISTA_OUTPUT T_LISTA_ELEMENTI;TERMINATORE VARCHAR2(3):='...';LUNGHEZZA_MAX NUMBER:=4000;BEGINIFSELF.LISTA_ELEMENTI.EXISTS(1)THEN-- se esiste almeno un elemento nella lista-- inizializza una nuova lista di appoggioLISTA_OUTPUT:=T_LISTA_ELEMENTI();-- riversamento dei soli elementi in DISTINCTLISTA_OUTPUT:=SELF.LISTA_ELEMENTI MULTISETUNIONDISTINCTSELF.LISTA_ELEMENTI;-- ordinamento degli elementiSELECTCAST(MULTISET(SELECT*FROMTABLE(LISTA_OUTPUT)ORDERBY1)AST_LISTA_ELEMENTI)INTOLISTA_OUTPUTFROMDUAL;-- concatenazione in una stringaFORIINLISTA_OUTPUT.FIRST..LISTA_OUTPUT.LAST-1LOOP
STRINGA_OUTPUT:=STRINGA_OUTPUT||LISTA_OUTPUT(I)||SELF.SEPARATORE;ENDLOOP;STRINGA_OUTPUT:=STRINGA_OUTPUT||LISTA_OUTPUT(LISTA_OUTPUT.LAST);-- se la stringa supera la dimensione massima impostata, tronca e termina con un terminatoreIFLENGTH(STRINGA_OUTPUT)>LUNGHEZZA_MAXTHENRETURN_VALUE:=SUBSTR(STRINGA_OUTPUT,0,LUNGHEZZA_MAX-LENGTH(TERMINATORE))||TERMINATORE;ELSERETURN_VALUE:=STRINGA_OUTPUT;ENDIF;ELSE-- se non esiste nessun elemento, restituisci NULLRETURN_VALUE:=NULL;ENDIF;RETURNODCICONST.SUCCESS;END;MEMBERFUNCTIONODCIAGGREGATEMERGE(SELFINOUT T_LISTAGG_DISTINCT,CTX2INT_LISTAGG_DISTINCT)RETURNNUMBERISBEGINRETURNODCICONST.SUCCESS;END;END;-- fine corpoCREATEFUNCTIONLISTAGG_DISTINCT(INPUT LISTAGG_DISTINCT_PARAMS)RETURNVARCHAR2
PARALLEL_ENABLE AGGREGATEUSINGT_LISTAGG_DISTINCT;//ExampleSELECTLISTAGG_DISTINCT(LISTAGG_DISTINCT_PARAMS(OWNER,', '))ASLISTA_OWNERFROMSYS.ALL_OBJECTS;