2016-05-24 16 views
2

Ich versuche, die COLLECT-Funktion für mich arbeiten zu lassen. Ich benutze 10g und habe daher festgestellt, dass LISTAGG und WM_CONCAT nicht funktionieren (ungültige Bezeichnerfehler). Die Daten, die ich habe, sind zum Beispiel wie folgt.Verwendung von COLLECT mit VARCHAR2 Oracle 10g

Order Lot 
123 A23088 
123 A23089 
089 AABBCC 
305 120848 
305 CCDDYY 

Was ich zurück müssen, ist, wie

folgt
Order Lot 
123  A23088, A23089 
089  AABBCC 
305  120848, CCDDYY 

die folgende Verwendung, erhalte ich die Fehlermeldung: TO_STRING eine ungültige Kennung

TO_STRING (CAST(COLLECT(DISTINCT LOT) AS varchar2(100))) AS LOT 

Mit Hilfe der folgenden Ergebnisse, ich den Fehler : erwartetes CHAR "inkonsistente Datentypen: erwartet% s hat% s"

TO_CHAR (CAST(COLLECT(DISTINCT LOT) AS varchar2(100))) AS LOT 

die folgende Verwendung, erhalte ich die Fehlermeldung: erwartete Anzahl „inkonsistente Datentypen: voraussichtlich% s bekam% s“

COLLECT(DISTINCT WHSE_LOT) 

Gibt es eine Möglichkeit, diese Funktion zu erhalten, für mich zu arbeiten?

Antwort

1

Die collect function erstellt eine geschachtelte Tabelle, in Ihrem Fall eine Tabelle mit Zeichenfolgen, die Sie dann in einen bestimmten Typ umwandeln würden, dh einen Typ, der als Tabelle von varchar2 definiert ist. Sie können nicht auf eine einzelne Zeichenfolge umwandeln.

Es gibt einige bekannte Listen von String-Aggregationstechniken, like this one. Es gibt eine , aber Sie benötigen immer noch den Tabellentyp und eine Funktion, um die generierte Tabelle in eine Zeichenfolge mit Trennzeichen zu konvertieren.

wörtlich dieses Beispiel Kopieren:

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; 
/

Mit dieser Art und Funktion, die Sie dann tun:

SELECT tab_to_string(CAST(COLLECT(DISTINCT lot) AS t_varchar2_tab)) AS lot FROM ... 

Interessanterweise scheint the 10g version of collect nicht DISTINCT unterstützen; Es klagen nicht (!?), aber hinterlässt Duplikate.

Sie können die Sammlung durch the set function passieren die Duplikate zu entfernen:

SELECT tab_to_string(SET(CAST(COLLECT(DISTINCT lot) AS t_varchar2_tab))) AS lot FROM ... 

Schnelldemolauf in 10.2.0.5:

create table table1(order_no number, lot varchar2(10)); 

insert into table1 values (590288, '2016538'); 
insert into table1 values (590288, '2016535'); 
insert into table1 values (590288, '6016535'); 
insert into table1 values (590288, '2016535'); 
insert into table1 values (590288, '2016538'); 

SELECT order_no, tab_to_string(SET(CAST(COLLECT(DISTINCT lot) AS t_varchar2_tab))) AS LOT 
FROM table1 WHERE order_no = 590288 GROUP BY order_no; 

    ORDER_NO LOT            
---------- -------------------------------------------------- 
    590288 2016538,2016535,6016535       
+0

Sie für die @AlexPoole Hilfe danken. Ich habe gefunden, dass diese Lösung mit einer Ausnahme funktioniert - es werden nicht nur eindeutige Werte zurückgegeben. Beispiel: SELECT SELECT order_no, tab_to_string (CAST (COLLECT (DISTINCT-Menge) AS t_varchar2_tab)) AS LOS VON Tabelle1 WHERE order_no = 590288 GROUP BY order_no; 'Retourenauftrag_No Lot 590288 2016535,2016535,6016535,2016538,2016538 Irgendwelche Vorschläge? – ESC

+0

@ESC - aktualisiert, um die Sammlung durch 'SET()' zu übergeben, um die Suplicates zu entfernen, da 10g 'COLLECT (DISTINCT ...)' nicht erkennt. –