将逗号分隔的批量字符串插入表中

时间:2014-12-02 10:29:42

标签: oracle

我有一个oracle存储过程,其中有一个变量

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中。 我怎么能这样做?

2 个答案:

答案 0 :(得分:0)

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

对于SQL方法,请使用以下任一方法:

使用 REGEXP

INSTR子句

中的

1。 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>
REGEXP_SUBSTR子句

中的

2。 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>
REGEXP_COUNT子句中的

3。 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>

答案 1 :(得分:0)

如果你有几千个条目,你可能需要将逗号列表作为CLOB而不是varchar传递,因为varchars在SQL中的最大长度为4000字节(在PL / SQL中为32K)

为了有效地执行此操作,您应该创建一个PL / SQL过程,该过程适用于列表并在Bulks中插入值(一次可能有大约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-Operations是一个潜在的危险,如果性能真的是一个问题,甚至可以在VARCHAR2中缓存CLOB的块以加快速度......但首先是基准测试!