2014-12-02 3 views
0

У меня есть хранимая процедура оракула, в котором у меня есть 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

Для этого вам нужно использовать язык программирования –

+0

Я новичок в PL SQL, можете ли вы рассказать мне, как это сделать? –

+0

'PL/SQL' необязательно требуется. Посмотрите на мой ответ. –

ответ

0

Если вы действительно хотите использовать PL/SQL, то есть смотреть на http://lalitkumarb.wordpress.com/2014/03/07/oracle-insert-comma-seperated-string-values-into-table/

Для SQL подхода, можно использовать любой из следующих действий:

Использование REGEXP

1.INSTR в CONNECT 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_SUBSTR в CONNECT 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_COUNT в CONNECT 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, этот подход не работает, поскольку я проверил его –

+0

Это потому, что 'string literal' не может быть больше, чем' 4000' символов. –

+0

Каково решение? –

0

Если у вас несколько тысяч записей, вам, скорее всего, нужно будет передать запятую как CLOB, а не varchar, потому что varchars имеют максимальную длину 4000 байт в SQL (и 32K в PL/SQL).

Чтобы сделать это эффективно, вы должны создать процедуру PL/SQL, который работает в списке и вставляет значения в набухает

процедура будет выглядеть примерно так (возможно, около 500 значений в то время?):

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-операции представляют собой потенциальную опасность, если производительность r eally - проблема, можно даже кэшировать куски CLOB в VARCHAR2, чтобы ускорить работу ... Но первый тест!