2016-05-24 10 views
2

私のためにCOLLECT関数を使用しようとしています。私は10gを使用しているので、LISTAGGとWM_CONCATは動作しません(無効な識別子エラー)。私が持っているデータは、例えば以下の通りです。以下のものを使用して、VARCHAR2でCOLLECTを使用する方法Oracle 10g

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

を次のように私は戻っ必要なもの

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

があり、私はエラーを取得:TO_STRINGは、以下のものを使用して、無効な識別子

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

で、私はエラーを取得します:期待されるCHARの「一貫性のないデータ型:期待される%sは%sです」

TO_CHAR (CAST(COLLECT(DISTINCT LOT) AS varchar2(100))) AS LOT 
次を使用して

、私はエラーを取得する:期待NUMBER「一貫性のないデータ型:期待%sのしまっ%s」の

COLLECT(DISTINCT WHSE_LOT) 

は私のために動作するように、この機能を取得する方法はありますか?

答えて

1

collect functionは、ネストした表を作成します。この場合、特定の型(つまり、varchar2の表として定義された型)にキャストする文字列の表を作成します。 1つの文字列にキャストすることはできません。

文字列集約手法のよく知られたリストがあります(like this one)。 that uses collectが1つありますが、引き続きテーブルタイプと、生成されたテーブルを区切り文字列に変換する関数が必要です。

逐語的にその例をコピー:そのタイプで

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

をしてください、あなたを機能:

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

興味深いことに、the 10g version of collectDISTINCTをサポートしていません。それは文句を言いません(!?)が、重複を残します。

あなたは重複を削除するthe set functionを通じてコレクションを渡すことができます:10.2.0.5で

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

クイックデモ走行:

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

は、ヘルプ@AlexPooleいただきありがとうございます。私は、このソリューションが1つの例外を伴って動作することを発見しました。たとえば、 'SELECT order_no、tab_to_string(CAST(COLLECT(DISTINCT lot)AS t_varchar2_tab))は、table1と同じです。WHERE order_no = 590288 GROUP BY order_no;'返品Order_Noロット590288 2016535,2016535,6016535,2016538,2016538何か提案がありますか? – ESC

+0

@ESC - 10gが 'COLLECT(DISTINCT ...) 'を認識しないので、コレクションを' SET() 'で渡すように更新しました。 –

関連する問題