2017-11-27 3 views
0

カンマ区切り文字列を使用して、各値を新しい行としてテーブルに挿入しようとしています。私は以下の例をLalit Kumar Bから取り上げ、データを変更して自分のデータがどのように見えるかを見てきました。カンマで区切られたリストがカンタ区切りで無効です。

DECLARE 
    L_INPUT VARCHAR2(4000) := '522,33-23,125,658,25,12-500'; 
    L_COUNT BINARY_INTEGER; 
    L_ARRAY DBMS_UTILITY.LNAME_ARRAY; 
BEGIN 
    DBMS_UTILITY.COMMA_TO_TABLE(LIST => REGEXP_REPLACE(L_INPUT, '(^|,)', '\1x'), TABLEN => L_COUNT, TAB => L_ARRAY); 
    DBMS_OUTPUT.PUT_LINE(L_COUNT); 
    FOR I IN 1 .. L_COUNT 
    LOOP 
     DBMS_OUTPUT.PUT_LINE('Element ' || TO_CHAR(I) || ' of array contains: ' || SUBSTR(L_ARRAY(I), 2)); 
     INSERT INTO TEST22 VALUES 
     (SUBSTR(L_ARRAY(I), 2) 
     ); 
     COMMIT; 
    END LOOP; 
END; 

私は、次のOracleエラー受けています:私は、フォームのデータを処理するために何ができるの33から23

の近くに「33から23」をカンマで区切ったリスト無効:ORA-20001の?私が「 - 」を自分のデータから取り除くならば、上記は望みどおりに実行されます。これは理想的ではありません。私のデータの中には「 - 」があり、それを削除することはできません。

+1

「dbms_utility.comma_to_table」プロシージャは何と思いますか?これはデータベース識別子( 'schema.table.column @ link'とそのバリエーションの形式)で動作することを意図しています。さて、カンマで区切った文字列を分割するだけで悪用するかもしれませんが、期待通りの結果は得られません。識別子にダッシュは許可されません。いずれにせよ、必要なものがカンマで区切られた文字列を分割することです。方法はありますが、 'comma_to_table'プロシージャはそれらの1つではありません。 – mathguy

+0

アンダースコアに置き換えてください –

+0

Wait ... Lalitは文字列を分割する方法としてこれを示していますか?それとも何か他の人に使っているのですか?彼が文字列を分割して表示している場合は、リンクを提供してください。有効なメソッドのリストからこのメソッドを削除する必要があります。 – mathguy

答えて

1

1つの方法は、CONNECT BYを使用して文字列要素を効果的にループすることです。クエリだけを実行すると、これがどのように機能するかがわかります。正規表現では、発生するはずのNULLリスト要素を使用できます。

insert into TEST(col_a) 
select regexp_substr('522,33-23,125,658,25,12-500', '(.*?)(,|$)', 1, level, null, 1) 
from dual 
connect by level <= regexp_count('522,33-23,125,658,25,12-500', ',')+1 
+0

私は正しい方向に向いてくれてありがとう。これが私の必要なものです。私は大きなインサートリストを持っていたので少し修正しなければなりませんでしたが、これは私が探していたものです。再度助けてくれてありがとう – Doug

0

DBMS_UTILITY.COMMA_TO_TABLEにも同じ問題がありました。数値文字列にはいくつかのバグがあります。私はいくつかの方法を試し、最後にこの関数を書きました。

CREATE OR REPLACE PACKAGE UTILITY_METHODS IS 

TYPE STRING_TAB IS TABLE OF VARCHAR2(512) INDEX BY BINARY_INTEGER; 

FUNCTION SPLIT_STR( P_STRING  IN VARCHAR2 
        , P_SEPRATOR_CHAR IN VARCHAR2) 
RETURN STRING_TAB; 

END UTILITY_METHODS; 

CREATE OR REPLACE PACKAGE BODY UTILITY_METHODS IS 

FUNCTION SPLIT_STR( P_STRING  IN VARCHAR2 
        , P_SEPRATOR_CHAR IN VARCHAR2) 
RETURN STRING_TAB 
IS 
    STR_TAB STRING_TAB; 
    L_SEP_CHAR VARCHAR2(1) := NVL(P_SEPRATOR_CHAR, ','); 
    L_PATERN VARCHAR2(10) := '[^' || L_SEP_CHAR || ']+'; 
BEGIN 
    IF P_STRING IS NULL THEN 
    RETURN STR_TAB; 
    END IF; 

    FOR RC IN (
       WITH L_LINE(STR) AS  
       (
       SELECT P_STRING 
       FROM DUAL 
      ) 
       SELECT REGEXP_SUBSTR(STR, L_PATERN, 1, LEVEL) SP_STR 
       FROM L_LINE 
       CONNECT BY LEVEL <= REGEXP_COUNT(STR, L_SEP_CHAR) + 1 
      ) 
    LOOP 
    STR_TAB(STR_TAB.COUNT) := RC.SP_STR; 
    END LOOP; 

    RETURN STR_TAB; 
END; 

END UTILITY_METHODS; 

この関数をselect文で使用する場合は、関数の戻り値の型をPIPE_LINEDに変更できます。

関連する問題