2011-09-26 2 views
3

J'ai de l'aide et a été conduit à this page et this explanation, qui devrait contenir un moyen efficace d'agréger les choses.Création d'une fonction d'agrégation sur Oracle 10g retournant erreur inutile

Il suggère d'utiliser de COLLECT fonction et d'autres choses personnalisées. J'essaie de m'entendre avec lui, mais les messages d'erreur (plus mon nouvel an) ne sont pas les plus utiles.

La fonction:

CREATE OR REPLACE TYPE t_varchar2_tab AS TABLE OF VARCHAR2(4000); 

CREATE OR REPLACE FUNCTION tab_to_string (
    p_varchar2_tab IN t_varchar2_tab, 
    p_delimiter  IN VARCHAR2 DEFAULT ',') 
RETURN VARCHAR2 IS 
    l_string  VARCHAR2(32767); 
BEGIN 
    FOR i IN p_varchar2_tab.FIRST .. p_varchar2_tab.LAST LOOP 
    IF i != p_varchar2_tab.FIRST THEN 
     l_string := l_string || p_delimiter; 
    END IF; 
    l_string := l_string || p_varchar2_tab(i); 
    END LOOP; 
    RETURN l_string; 
END tab_to_string; 

Et mes tests:

with my_table as 
(
    select 'user1' as usrid, 'ab' as prodcode from dual union 
    select 'user1' as usrid, 'bb' as prodcode from dual union 
    select 'user1' as usrid, 'a' as prodcode from dual union 
    select 'user2' as usrid, 'db' as prodcode from dual union 
    select 'user2' as usrid, 'b' as prodcode from dual union 
    select 'user2' as usrid, 'bfdd' as prodcode from dual 
) 
select 
    usrid, 
    tab_to_string(CAST(COLLECT(prodcode) AS t_varchar2_tab)) AS codes 
from 
    my_table 
group by 
    usrid 

me donner une ORA-06553: PLS-306: wrong number or types of arguments in call to 'TAB_TO_STRING'

C'est à peu près copie et passé de la source que je mentionne dans la début, et la fonction a un sens pour moi .. qu'est-ce qui me manque?

merci!

[EDIT] Codo a compris que l'un des problèmes était Oracle comprendre le 'a' comme omble chevalier, plutôt que varchar. Cela a amené la question au vrai problème. Je l'ai mis à jour pour qu'il soit ciblé.

+0

si vous excluez le i IF = p_varchar2_tab.FIRST ALORS l_string: = l_string || p_delimiter; FIN SI; ce qui se produit? –

+0

@FlorinGhita Aucun changement .. même erreur. Idée? – filippo

+0

@filippo: Votre exemple ne fonctionne plus. Si toutes les valeurs de la colonne 'prodcode' ont la même longueur, il utilise le type' CHAR' au lieu de 'VARCHAR'. En dehors de cela, avez-vous essayé 'tab_to_string (CAST (COLLECT (prodcode) AS t_varchar2_tab), ',')' comme je l'ai proposé hier? (Sur Oracle 11g, ça marche quand même.) – Codo

Répondre

2

Pour des raisons que je ne comprends pas vraiment, Oracle pense que la colonne PRODCODE de votre table synthétique n'est pas une colonne VARCHAR2. Si vous modifiez légèrement l'une des valeurs PRODCODE, ça va marcher:

with my_table as 
(
    select 'user1' as usrid, 'ab' as prodcode from dual union 
    select 'user1' as usrid, 'b' as prodcode from dual union 
    select 'user1' as usrid, 'c' as prodcode from dual union 
    select 'user2' as usrid, 'd' as prodcode from dual union 
    select 'user2' as usrid, 'e' as prodcode from dual union 
    select 'user2' as usrid, 'f' as prodcode from dual 
) 
select 
    usrid, 
    tab_to_string(CAST(COLLECT(prodcode) AS t_varchar2_tab)) AS codes 
from 
    my_table 
group by 
    usrid 
+1

Je soupçonne que «a» est de type «CHAR» – Benoit

+0

Ouf, c'est super boiteux, mais a fait l'affaire. Non, l'erreur que j'ai est le 'PLS-306: mauvais nombre ou types d'arguments'. Des pensées là-dessus? – filippo

+0

Sur Oracle 11g, si je change 'a' en 'ab', cela fonctionne sans autre modification. Je peux seulement deviner: vous avez peut-être explicitement spécifier le deuxième paramètre 'p_delimiter' dans 10g. – Codo