programing

자동 시퀀스를 사용하여 쉼표로 구분된 값으로 오라클의 함수를 분할합니다.

lastmoon 2023. 4. 2. 11:50
반응형

자동 시퀀스를 사용하여 쉼표로 구분된 값으로 오라클의 함수를 분할합니다.

분할 함수는 분할할 문자열과 문자열을 분할하고 Id 및 Data 열이 있는 테이블을 반환하는 구분 기호라는 두 개의 매개 변수를 필요로 합니다.또한 Id 및 Data 열의 테이블을 반환하는 Split 함수를 호출하는 방법.ID 열에는 시퀀스가 포함되어 데이터 열에는 문자열의 데이터가 포함됩니다.예.

SELECT*FROM Split('A,B,C,D',',')

결과는 다음 형식이어야 합니다.

|Id | Data
 --   ----
|1  | A  |
|2  | B  |
|3  | C  |
|4  | D  |

이러한 테이블을 작성하는 방법은 다음과 같습니다.

 SELECT LEVEL AS id, REGEXP_SUBSTR('A,B,C,D', '[^,]+', 1, LEVEL) AS data
   FROM dual
CONNECT BY REGEXP_SUBSTR('A,B,C,D', '[^,]+', 1, LEVEL) IS NOT NULL;

「」의 을 실시합니다.,[^,]변수)를 사용하여 테이블을 반환하는 함수를 작성할 수 있습니다.

여러 가지 옵션이 있습니다.Oracle에서 단일 쉼표로 구분된 문자열을 행으로 분할을 참조하십시오.

선택 목록에서 LEVEL을 열로 추가하면 반환되는 각 행의 시퀀스 번호를 얻을 수 있습니다.아니면 ROWNUM으로도 충분합니다.

아래 SQL 중 하나를 사용하여 함수에 포함할 수 있습니다.

CONNECT BY INSTR:

SQL > 데이터 AS 사용2('word1, word2, word3, word4, word5, word6' str From dual3    )4 SELECT trim(regexp_substr(str, '[^,]+', 1, LEVEL) str)5 데이터로부터6 instr(str, ', 1, LEVEL - 1)> 0으로 접속7  /
STR----------------------------------------워드1워드2워드3워드4단어 5워드6
6 행을 선택했습니다.

SQL >

CONNECT BY 의 REGEXP_SUBstr:

SQL > 데이터 AS 사용2('word1, word2, word3, word4, word5, word6' str From dual3    )4 SELECT trim(regexp_substr(str, '[^,]+', 1, LEVEL) str)5 데이터로부터6 regexp_substr(str, '[^,]+', 1, LEVEL)에 의한 접속은 null이 아닙니다.7  /
STR----------------------------------------워드1워드2워드3워드4단어 5워드6
6 행을 선택했습니다.

SQL >

CONNECT BY REGEXP_COUNT:

SQL > 데이터 AS 사용2('word1, word2, word3, word4, word5, word6' str From dual3        )4 SELECT trim(regexp_substr(str, '[^,]+', 1, LEVEL) str)5 데이터로부터6 레벨별 접속

XMLTAB 사용LE

SQL > 데이터 AS 사용2('word1, word2, word3, word4, word5, word6' str From dual3    )4 SELECT 트림(COLUMN_VALUE) 스트링5 FROM DATA, xmltable(') || REPLACE(str, '', '', '', | ''')6  /STR------------------------------------------------------------------------워드1워드2워드3워드4단어 5워드6
6 행을 선택했습니다.

SQL >

MODEL 절 사용:

SQL > t AS 사용2  (3 'word1, word2, word3, word4, word5, word6' 스트링을 선택합니다.4 듀얼 )부터,5 model_param AS6  (7 SELECT str AS orig_str,8                ','9 || str10 | | ' , AS mod_str ,11 1 AS start_pos,12 Length(str) AS end_pos,13(Length(str) - Length(Replace(str, ' , )) + 1 AS element_count,14 0 AS 요소_no,15 ROWNUM AS rn16 시작 t )17 SELECT 트림(Substr(mod_str, start_pos, end_pos-start_pos) str)18 시작(19 선택*20 from model_param model 파티션 기준(rn, orig_str, mod_str)21 치수 기준(Element_no)22 측정(start_pos, end_pos, element_count)23 규칙 반복 (2000)24까지 (반복_NUMBER+1 = element_count[0])25 ( start _ pos [ )RETHERATION_NUMBER+1] = instr(instr(mod_str), '', 1, cv(mod_no) + 1,26 end_pos[iteration_number+1] = instr(inst(mod_str), '', 1, cv(cv_no) + 1) )27 WHERE 요소_no!= 028 mod_str에 의한 주문,29 요소_no30  /
STR------------------------------------------워드1워드2워드3워드4단어 5워드6
6 행을 선택했습니다.

SQL >

오라클에서 제공하는 DBMS_UTILITY 패키지를 사용할 수도 있습니다.다양한 유틸리티 서브프로그램을 제공합니다.이러한 유용한 유틸리티 중 하나는 COMA_TO_입니다.TABLE 프로시저: 쉼표로 구분된 이름 목록을 이름의 PL/SQL 테이블로 변환합니다.

DBMS_UTILITY를 읽습니다.콤마_TO_테이블

Oracle 셋업:

CREATE OR REPLACE FUNCTION split_String(
  i_str    IN  VARCHAR2,
  i_delim  IN  VARCHAR2 DEFAULT ','
) RETURN SYS.ODCIVARCHAR2LIST DETERMINISTIC
AS
  p_result       SYS.ODCIVARCHAR2LIST := SYS.ODCIVARCHAR2LIST();
  p_start        NUMBER(5) := 1;
  p_end          NUMBER(5);
  c_len CONSTANT NUMBER(5) := LENGTH( i_str );
  c_ld  CONSTANT NUMBER(5) := LENGTH( i_delim );
BEGIN
  IF c_len > 0 THEN
    p_end := INSTR( i_str, i_delim, p_start );
    WHILE p_end > 0 LOOP
      p_result.EXTEND;
      p_result( p_result.COUNT ) := SUBSTR( i_str, p_start, p_end - p_start );
      p_start := p_end + c_ld;
      p_end := INSTR( i_str, i_delim, p_start );
    END LOOP;
    IF p_start <= c_len + 1 THEN
      p_result.EXTEND;
      p_result( p_result.COUNT ) := SUBSTR( i_str, p_start, c_len - p_start + 1 );
    END IF;
  END IF;
  RETURN p_result;
END;
/

쿼리

SELECT ROWNUM AS ID,
       COLUMN_VALUE AS Data
FROM   TABLE( split_String( 'A,B,C,D' ) );

출력:

ID DATA
-- ----
 1 A
 2 B
 3 C
 4 D

★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
먼저 유형을 만듭니다.

CREATE OR REPLACE TYPE T_TABLE IS OBJECT
(
    Field1 int
    , Field2 VARCHAR(25)
);
CREATE TYPE T_TABLE_COLL IS TABLE OF T_TABLE;
/

그런 다음 다음 함수를 만듭니다.

CREATE OR REPLACE FUNCTION TEST_RETURN_TABLE
RETURN T_TABLE_COLL
    IS
      l_res_coll T_TABLE_COLL;
      l_index number;
    BEGIN
      l_res_coll := T_TABLE_COLL();
      FOR i IN (
        WITH TAB AS
          (SELECT '1001' ID, 'A,B,C,D,E,F' STR FROM DUAL
          UNION
          SELECT '1002' ID, 'D,E,F' STR FROM DUAL
          UNION
          SELECT '1003' ID, 'C,E,G' STR FROM DUAL
          )
        SELECT id,
          SUBSTR(STR, instr(STR, ',', 1, lvl) + 1, instr(STR, ',', 1, lvl + 1) - instr(STR, ',', 1, lvl) - 1) name
        FROM
          ( SELECT ',' || STR || ',' AS STR, id FROM TAB
          ),
          ( SELECT level AS lvl FROM dual CONNECT BY level <= 100
          )
        WHERE lvl <= LENGTH(STR) - LENGTH(REPLACE(STR, ',')) - 1
        ORDER BY ID, NAME)
      LOOP
        IF i.ID = 1001 THEN
          l_res_coll.extend;
          l_index := l_res_coll.count;
          l_res_coll(l_index):= T_TABLE(i.ID, i.name);
        END IF;
      END LOOP;
      RETURN l_res_coll;
    END;
    /

여기서 선택할 수 있습니다.

select * from table(TEST_RETURN_TABLE()); 

출력:

SQL> select * from table(TEST_RETURN_TABLE());

    FIELD1 FIELD2
---------- -------------------------
      1001 A
      1001 B
      1001 C
      1001 D
      1001 E
      1001 F

6 rows selected.

'아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아WITH TAB AS... 실제 데이터를 어디서 얻을 수 있는지에 대한 정보를 제공합니다.크레디트 크레디트

다음 '분할' 함수를 사용합니다.

CREATE OR REPLACE FUNCTION Split (p_str varchar2) return sys_refcursor is
v_res sys_refcursor;

begin
  open v_res for 
  WITH TAB AS 
  (SELECT p_str STR FROM DUAL)
  select substr(STR, instr(STR, ',', 1, lvl) + 1, instr(STR, ',', 1, lvl + 1) - instr(STR, ',', 1, lvl) - 1) name 
  from
    ( select ',' || STR || ',' as STR from TAB ),
    ( select level as lvl from dual connect by level <= 100 )
    where lvl <= length(STR) - length(replace(STR, ',')) - 1;

     return v_res;
   end;

이 기능은, 문제의 설명과 같이 select 스테이트먼트에서는 사용할 수 없지만, 그래도 도움이 되었으면 합니다.

편집: 필요한 절차는 다음과 같습니다. 1. 개체 만들기: empy_type을 개체(value varchar2(512) 2)로 만들거나 바꿉니다.[Create Type] :t_empty_type을 empy_type 3 테이블로 만들거나 바꿉니다.함수 생성:

CREATE OR REPLACE FUNCTION Split (p_str varchar2) return sms.t_empty_type is
v_emptype t_empty_type := t_empty_type();
v_cnt     number := 0;
v_res sys_refcursor;
v_value nvarchar2(128);
begin
  open v_res for
  WITH TAB AS
  (SELECT p_str STR FROM DUAL)
  select substr(STR, instr(STR, ',', 1, lvl) + 1, instr(STR, ',', 1, lvl +     1) - instr(STR, ',', 1, lvl) - 1) name
  from
    ( select ',' || STR || ',' as STR from TAB ),
    ( select level as lvl from dual connect by level <= 100 )
    where lvl <= length(STR) - length(replace(STR, ',')) - 1;


  loop
     fetch v_res into v_value;
      exit when v_res%NOTFOUND;
      v_emptype.extend;
      v_cnt := v_cnt + 1;
     v_emptype(v_cnt) := empty_type(v_value);
    end loop;
    close v_res;

    return v_emptype;
end;

그럼 이렇게 불러주세요.

SELECT * FROM (TABLE(split('a,b,c,d,g'))) 

이 함수는 입력 문자열 MISTRING의 n번째 부분을 반환합니다. 두 번째 입력 매개 변수는 구분자(SEPERATOR_OF_SUBSTR)이고 세 번째 매개 변수는 N번째 부분(필수)입니다.

주의: MISTRING은 구분자로 끝나야 합니다.

create or replace FUNCTION PK_GET_NTH_PART(MYSTRING VARCHAR2,SEPARATOR_OF_SUBSTR VARCHAR2,NTH_PART NUMBER)
RETURN VARCHAR2
IS
NTH_SUBSTR VARCHAR2(500);
POS1 NUMBER(4);
POS2 NUMBER(4);
BEGIN
IF NTH_PART=1 THEN
SELECT REGEXP_INSTR(MYSTRING,SEPARATOR_OF_SUBSTR, 1, 1)  INTO POS1 FROM DUAL; 
SELECT SUBSTR(MYSTRING,0,POS1-1) INTO NTH_SUBSTR FROM DUAL;
ELSE
SELECT REGEXP_INSTR(MYSTRING,SEPARATOR_OF_SUBSTR, 1, NTH_PART-1) INTO  POS1 FROM DUAL; 
SELECT REGEXP_INSTR(MYSTRING,SEPARATOR_OF_SUBSTR, 1, NTH_PART)  INTO POS2 FROM DUAL; 
SELECT SUBSTR(MYSTRING,POS1+1,(POS2-POS1-1)) INTO NTH_SUBSTR FROM DUAL;
END IF;
RETURN NTH_SUBSTR;
END;

이것이 본문에 도움이 되기를 바랍니다.이 함수를 루프에서 사용하여 모든 값을 분리할 수 있습니다.

SELECT REGEXP_COUNT(MYSTRING, '~', 1, 'i') INTO NO_OF_RECORDS FROM DUAL;
WHILE NO_OF_RECORDS>0
LOOP
    PK_RECORD    :=PK_GET_NTH_PART(MYSTRING,'~',NO_OF_RECORDS);
    -- do some thing
    NO_OF_RECORDS  :=NO_OF_RECORDS-1;
END LOOP;

여기서 NO_OF_RECORD, PK_RECORD는 온도 변수입니다.

이게 도움이 됐으면 좋겠다.

이 쿼리에서 구분된 쉼표에 대한 최상의 쿼리 행은 열로 변환합니다...

SELECT listagg(BL_PRODUCT_DESC, ', ') within
   group(   order by BL_PRODUCT_DESC) PROD
  FROM GET_PRODUCT
--  WHERE BL_PRODUCT_DESC LIKE ('%WASH%')
  WHERE Get_Product_Type_Id = 6000000000007

지정된 딜리미터로 문자열을 분할하여 결과를 VARRAY로 반환할 수 있는 PL/SQL 함수를 만들었습니다.

CREATE OR REPLACE FUNCTION split(p_parameters VARCHAR2, p_delimiter VARCHAR2) RETURN string_varray AS
    v_delimiter_position NUMBER := 0;
    v_read_position NUMBER :=1;
    v_list string_varray := string_varray();
    v_substring VARCHAR2(4000);
    
    FUNCTION normalize(v_substring VARCHAR2, p_delimiter VARCHAR2) RETURN VARCHAR2 AS
    BEGIN
        RETURN trim(TRAILING p_delimiter FROM trim(BOTH ' ' FROM v_substring));
    END normalize;
BEGIN
    LOOP
         v_delimiter_position := instr(p_parameters, p_delimiter, v_read_position);
         IF v_delimiter_position = 0 THEN
            v_delimiter_position := LENGTH(p_parameters);
         END IF;
         v_substring := substr(p_parameters, v_read_position, v_delimiter_position-v_read_position+1);
         v_list.EXTEND;
         v_list(v_list.LAST) := normalize(v_substring, p_delimiter);
         v_read_position := v_delimiter_position+1;
         IF v_delimiter_position = LENGTH(p_parameters) THEN
            EXIT;
         END IF; 
    END LOOP;  

    RETURN v_list;
END split;

string_varray는 VARCHAR2(4000) 유형의 VARRAY입니다.이 함수는 공백과 각 값의 시작 및 끝도 제거합니다.호출 예:

select * from table(split('zaa, dddd,ccc', ','));

출력에 zaa ddd ccc라는3개의 행이 생성됩니다.

여기에 이미지 설명 입력

rec in에 대해 시작합니다(테이블에서 *를 선택합니다('table shfgjsdfg,242535', '',). 루프 dbms_output).put_line(rec).COLUMN_VALUE);

엔드 루프; 엔드;

-- 출력 shfgjsdfg 242535

다음과 같이 시도합니다.

select 
    split.field(column_name,1,',','"') name1,
    split.field(column_name,2,',','"') name2
from table_name

언급URL : https://stackoverflow.com/questions/28677070/split-function-in-oracle-to-comma-separated-values-with-automatic-sequence

반응형