[오라클] 내장함수 SUBSTR을 프로시저로 구현

in #oracle6 years ago

이게 제일 어려웠다..진심...이런걸 과제로 내주는 학교의 교수는 얼마나 천재인가...

REPLACE와 같은 맥락으로 만든것인데...사실 SUBSTRC는 유니코드단위로 글자를 쪼개는 것이라 크게 의미는 없다. 요청자는 SUBSTR을 사용하지 않으면 되는 것이라 대체재로 사용했는데... 생각보다 쓸만하다. 프로시저가 아니라 SUBSTRC가... 처음엔 SUBSTRB도 사용하려했지만... 한글이나 영어가 차지하는 BYTE수가 달라 사용하지 못했다.

혹시 오라클에서 VARCHAR형의 문자열을 SUBSTR을 사용하지 않고 한글자, 한글자 나누실 수 있는분 있다면 알려주세요 ㅜㅜ

create or replace PROCEDURE SUBSTR_PROCEDURE
( 
  STR VARCHAR,      --원본데이터
  CSTART NUMBER,    --시작인덱스
  CEND NUMBER       --끝인덱스
)
IS
 CRETURN VARCHAR(200);
BEGIN
    --SUBSTRB는 바이트로 쪼갬
    CRETURN := SUBSTRC(STR, CSTART, CEND);
    
    dbms_output.put_line(CRETURN);
  
END SUBSTR_PROCEDURE;

변경 SUBSTRB를 이용하여 BYTE단위로 자름. 한글 처리, 공백처리 완료, BUT `문자는 사용할 수 없음.

create or replace PROCEDURE SUBSTR_PROCEDURE
( 
  STR VARCHAR,
  CSTART NUMBER,
  CEND NUMBER
)
IS
 CSTR VARCHAR(200);
 CRETURN VARCHAR(200);
 CRETURNTEMP VARCHAR(200);
 CTEMP VARCHAR(200);
 CLOOP NUMBER;
BEGIN
    --아래부분에 LOGIC을 구현할것.
    
    CLOOP := 1;
    CSTR := REPLACE(STR, ' ', '`');
    LOOP
      CASE WHEN TRIM(SUBSTRB(CSTR, CLOOP, 1)) IS NOT NULL 
           THEN CTEMP := TRIM(SUBSTRB(CSTR, CLOOP, 1));
                CLOOP := CLOOP+1;
           WHEN TRIM(SUBSTRB(CSTR, CLOOP, 2)) IS NOT NULL
           THEN CTEMP := TRIM(SUBSTRB(CSTR, CLOOP, 2));
                CLOOP := CLOOP+2;
           ELSE CTEMP := TRIM(SUBSTRB(CSTR, CLOOP, 3)); 
                CLOOP := CLOOP+3;
      END CASE;
      CRETURNTEMP := CONCAT(CRETURNTEMP, CTEMP);
      IF LENGTH(CRETURNTEMP) BETWEEN CSTART AND (CSTART+CEND-1) THEN CRETURN := CONCAT(CRETURN, CTEMP); 
      END IF;
      EXIT WHEN CLOOP > LENGTHB(CSTR);
    END LOOP;
    
    dbms_output.put_line(REPLACE(CRETURN, '`', ' '));
  
END SUBSTR_PROCEDURE;

SUBSTR시리즈를 쓰면 안된단다...아예 다른 방법을 생각해 ASCII(문자열)을 할시 맨 앞에 문자의 ASCII값만 나온다는 것에서 착안하여 만들어봤다.

create or replace PROCEDURE SUBSTR_PROCEDURE
( 
  STR VARCHAR,
  CSTART NUMBER,
  CEND NUMBER
)
IS
 CSTR VARCHAR(200);
 CRETURN VARCHAR(200);
 CRETURNTEMP VARCHAR(200);
 CTEMP VARCHAR(200);
 CLOOP NUMBER;
BEGIN
    --아래부분에 LOGIC을 구현할것.
    
    CLOOP := 1;
    CSTR := STR; --CSTR에 PARAMETER를 입력
    IF STR IS NOT NULL THEN
      LOOP
      CTEMP := CHR(ASCII(CSTR)); --ASCII(문자열)을 하면 맨앞에 대한 ASCII값만 나오게 되있음. 그걸 다시 CHR(ASCII)로 문자 하나로 변경
      CSTR := REPLACE(CSTR, CTEMP, NULL); --REPLACE를 하여 나온 문자하나를 NULL로 변경
      CRETURNTEMP := CONCAT(CRETURNTEMP, CTEMP); --이후로직은 SUBSTRB랑 같음
      IF LENGTH(CRETURNTEMP) BETWEEN CSTART AND (CSTART+CEND-1) THEN CRETURN := CONCAT(CRETURN, CTEMP); 
      END IF;
      CLOOP := CLOOP + 1;
      EXIT WHEN CLOOP > LENGTH(STR);
    END LOOP;
    ELSE 
      CRETURN := NULL;
    END IF;
    dbms_output.put_line(CRETURN);
  
END SUBSTR_PROCEDURE;