2017-11-27 10 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'프로시 저는 그 중 하나가 아닙니다. – mathguy

+0

밑줄로 바꾸십시오 –

+0

기다려주세요 ... 문자열을 분할하는 방법으로이를 보여주는 Lalit이 있습니까? 아니면 다른 용도로 사용하고 있습니까? 그가 문자열을 나누어서 보여주고 있다면 링크를 제공하십시오. 그는 유효한 메소드 목록에서이 메소드를 제거해야합니다. – mathguy

답변

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로 변경할 수 있습니다.