2014-12-02 72 views
0

我有Oracle存儲過程中,我有一個varible插入逗號分隔散裝串入表

ids = '409065,93254,1000493402,133485,1002200674,1002686682,1000933402,1001671843,73164,1000480564,1002739956,1002228048,502731,1005114779,1004490734,1000830271,1000736038,1002728806,1007286917,1017655201,433535,1000416343,1001961884,178764,1000386274,1000392797,75272,282774,385409,1002759663,1002759515,1002862987,1005408942,1002945068,1004186393,1004273792,1002796666,1010443861,1002542001,1002933043,1000583061,1003171856,102229,1003485036,480827,1002365185,1001444669,149055,1002737902,1006296285,1005911768,478164,163635,1000760087,1003407655,1000285184,466212,1005094662,1006186285,1001345121,1003980207,1002760459,1000284633,1002591304,1001733016,1002736035,1002173855,1001954063,1002286714,201057,1000364289,1002003097,19542,16594,1004457516,1003280442,1002455699,1002541005,1004433471,642932,1000286571,1000633786,1002881698,1001961388,537829,1005411854,1013084048,1014240809,389536,232068,65951,1001579289,286176,1002584197,1002692879,1001673714,1002609262,1002745255,1002763229,1004692175,1001889555,1002752278,1001386316,1013052324,1000368098,279633,80896,1002743147,1000675179,1000284102,58017,1001630012,1000485329,1003438356,1004912086,1003460394,1012132693,409065,93254,1000493402,133485,1002200674,1002686682,1000933402,1001671843,73164,1000480564,1002739956,1002228048,502731,1005114779,1004490734,1000830271,1000736038,1002728806,1007286917,1017655201,433535,1000416343,1001961884,178764,1000386274,1000392797,75272,282774,385409,1002759663,1002759515,1002862987,1005408942,1002945068,1004186393,1004273792,1002796666,1010443861,1002542001,1002933043,1000583061,1003171856,102229,1003485036,480827,1002365185,1001444669,149055,1002737902,1006296285,1005911768,478164,163635,1000760087,1003407655,1000285184,466212,1005094662,1006186285,1001345121,1003980207,1002760459,1000284633,1002591304,1001733016,1002736035,1002173855,1001954063,1002286714,201057,1000364289,1002003097,19542,16594,1004457516,1003280442,1002455699,1002541005,1004433471,642932,1000286571,1000633786,1002881698,1001961388,537829,1005411854,1013084048,1014240809,389536,232068,65951,1001579289,286176,1002584197,1002692879,1001673714,1002609262,1002745255,1002763229,1004692175,1001889555,1002752278,1001386316,1013052324,1000368098,279633,80896,1002743147,1000675179,1000284102,58017,1001630012,1000485329,1003438356,1004912086,1003460394,1012132693,409065,93254,1000493402,133485,1002200674,1002686682,1000933402,1001671843,73164,1000480564,1002739956,1002228048,502731,1005114779,1004490734,1000830271,1000736038,1002728806,1007286917,1017655201,433535,1000416343,1001961884,178764,1000386274,1000392797,75272,282774,385409,1002759663,1002759515,1002862987,1005408942,1002945068,1004186393,1004273792,1002796666,1010443861,1002542001,1002933043,1000583061,1003171856,102229,1003485036,480827,1002365185,1001444669,149055,1002737902,1006296285,1005911768,478164,163635,1000760087,1003407655,1000285184,466212,1005094662,1006186285,1001345121,1003980207,1002760459,1000284633,1002591304,1001733016,1002736035,1002173855,1001954063,1002286714,201057,1000364289,1002003097,19542,16594,1004457516,1003280442,1002455699,1002541005,1004433471,642932,1000286571,1000633786,1002881698,1001961388,537829,1005411854,1013084048,1014240809,389536,232068,65951,1001579289,286176,1002584197,1002692879,1001673714,1002609262,1002745255,1002763229,1004692175,1001889555,1002752278,1001386316,1013052324,1000368098,279633,80896,1002743147,1000675179,1000284102,58017,1001630012,1000485329,1003438356,1004912086,1003460394,1012132693,19542,232068,16594,286176,1004433471,1001444669,1002759515,1000830271,1006186285,1002945068,1003001411,1006631785,1012132693,1012272096,1017655201,433535,93254,1000368098,1001961884,1001733016,133485,1002286714,149055,466212,1001889555,1000285656,1002760459,1000284633,1000583061,1003171856,178764,1001954063,1002455699,1000386274,1000285184,1002745255,1002759663,1002003097,1000284102,58017,1002455699,1002365185,1003407655,1002609262,1002686682,537829,19542,1006186285,409065,1002862987,1000933402,478164,1002945068,1002173855,1002200674,1007286917,1014240809,1001954063,1004273792,1001444669,1002728806,1002743147,1002286714,1001630012,286176,1017655201,178764,1012132693,1002736035,1005114779,1012272096,1003171856,1004912086,1005408942,102229,133485,163635,1006631785,1013052324,1002752278,1000285656,1005411854,80896,1003438356,1001733016,1000493402,1000583061,389536,433535,1000368098,1003460394,1000633786,1001671843,480827,1003485036,1002692879,1001673714,1004490734,1000830271,279633,1000284633,149055,16594,642932,1002003097,65951,466212,1001386316,1002737902,1002763229,1000480564,1000364289,1002745255,1000285184,1002759663,1002739956,1000760087,1002591304,1013084048,385409,1000286571,1002228048,1002796666,232068,1002881698,1004692175,1002759515,1000416343,1010443861,282774,73164,75272,1004457516,1002760459,1001579289,1005911768,1001889555,1000736038,1003001411,1001961388,1005094662,1001961884,1000485329,1002542001,201057,1003280442,1003980207,502731,1002933043,1004186393,93254,1001345121,1000675179,1002584197,1000392797,1000386274,1004433471,1002541005' 

它可以包含1000名以上的條目。現在我有表格TEMP_HI(ID VARCHAR2(200)),我想分割每個由逗號分隔的條目,並將其插入表TEMP_HI中。 我該怎麼做?

+0

你需要使用一種編程語言來做到這一點 – 2014-12-02 10:32:15

+0

我是PL SQL新手,你能告訴我該怎麼做嗎? – 2014-12-02 10:34:27

+0

'PL/SQL'不一定是必需的。看看我的答案。 – 2014-12-02 10:53:47

回答

0

如果你真的想用PL/SQL,然後看看http://lalitkumarb.wordpress.com/2014/03/07/oracle-insert-comma-seperated-string-values-into-table/

對於SQL方法,使用任何如下:

使用REGEXP在

INSTRCONNECT BY子句

SQL> WITH DATA AS 
    2 (SELECT '409065,93254,1000493402,133485,1002200674,1002686682' ids FROM dual 
    3 ) 
    4 SELECT regexp_substr(ids, '[^,]+', 1, LEVEL) ids 
    5 FROM DATA 
    6 CONNECT BY instr(ids, ',', 1, LEVEL - 1) > 0 
    7/

IDS 
---------------------------------------------------- 
409065 
93254 
1000493402 
133485 
1002200674 
1002686682 

6 rows selected. 

SQL> 

2.REGEXP_SUBSTRCONNECT BY子句

SQL> WITH DATA AS 
    2 (SELECT '409065,93254,1000493402,133485,1002200674,1002686682' ids FROM dual 
    3 ) 
    4 SELECT regexp_substr(ids, '[^,]+', 1, LEVEL) ids 
    5 FROM DATA 
    6 CONNECT BY regexp_substr(ids , '[^,]+', 1, LEVEL) IS NOT NULL 
    7/

IDS 
---------------------------------------------------- 
409065 
93254 
1000493402 
133485 
1002200674 
1002686682 

6 rows selected. 

SQL> 

3.REGEXP_COUNTCONNECT BY子句

SQL> WITH DATA AS 
    2 (SELECT '409065,93254,1000493402,133485,1002200674,1002686682' ids FROM dual 
    3 ) 
    4 SELECT regexp_substr(ids, '[^,]+', 1, LEVEL) ids 
    5 FROM DATA 
    6 CONNECT BY LEVEL <= regexp_count(ids, ',')+1 
    7/

IDS 
---------------------------------------------------- 
409065 
93254 
1000493402 
133485 
1002200674 
1002686682 

6 rows selected. 

SQL> 

使用XML

SQL> WITH DATA AS 
    2 (SELECT '409065,93254,1000493402,133485,1002200674,1002686682' ids FROM dual 
    3 ) 
    4 SELECT trim(COLUMN_VALUE) ids 
    5 FROM DATA, xmltable(('"' || REPLACE(ids, ',', '","') || '"')) 
    6/

IDS 
-------------------------------------------------------------------------------- 
409065 
93254 
1000493402 
133485 
1002200674 
1002686682 

6 rows selected. 

SQL> 
+0

當條目數超過10000時,這種方法不起作用,因爲我檢查了它 – 2014-12-02 11:01:27

+0

這是因爲'字符串文字'不能超過'4000'字符。 – 2014-12-02 11:06:44

+0

這是什麼解決方案? – 2014-12-02 11:39:39

0

如果你有幾千個條目,你可能需要通過逗號列表作爲CLOB而非VARCHAR,因爲VARCHAR處理有4000個字節的SQL的最大長度(和32K在PL/SQL)

(?也許有500個值在一個時間)要做到這一點有效,你應該創建一個PL/SQL程序,其工作清單上,並插入散貨值

的過程看起來有點像這樣:

PROCEDURE insert_comma_list(comma_list IN CLOB) 
IS 
    TYPE  array_t IS VARRAY(1000) OF VARCHAR2(100); 
    number_list array_t := array_t(); 
    index_old PLS_INTEGER := 1; 
    idx  PLS_INTEGER; 
    i   PLS_INTEGER; 
    list_length PLS_INTEGER := DBMS_LOB.GETLENGTH(comma_list); 
BEGIN 
    number_list.extend(1000); 
    WHILE index_old <= list_length LOOP 
    i := 1; 
    WHILE i <= 1000 AND index_old <= list_length LOOP 
     idx := DBMS_LOB.INSTR(comma_list, ',', index_old); 
     IF idx = 0 
     THEN 
     idx := list_length + 1; 
     END IF; 
     dbms_output.put_line(i || ': ' || index_old || ' - ' || idx); 
     number_list(i) := DBMS_LOB.SUBSTR(comma_list, idx - index_old, index_old); 
     index_old := idx + 1; 
     i := i + 1; 
    END LOOP; 

    FORALL array_row IN 1..i-1 
     INSERT INTO test_table_x VALUES (number_list(array_row)); 
    END LOOP; 
END; 

這應該足夠快,但如果性能確實如此,CLOB操作是潛在的危險是一個問題,甚至可以將CLOB的塊緩存在VARCHAR2中以加快速度......但首先是基準!