본문 바로가기
DATABASE/ORACLE

[ORACLE] FUNCTION 생성: 숫자에 단위 표시(구분자로) & 숫자를 한글로 읽은 것 출력하는 함수 [FOR ~LOOP, IF - ELSE, CURSOR - FETCH]

by sjs_2215 2019. 11. 10.
  • 하려는 것

숫자 파라메타 값으로 입력, (2개)
1 구분자 2 숫자
구분자: 금액 표시하는 것처럼 컴마 찍어주기
1,234,578
아웃풋:
숫자 받으면 한글로 읽어주기 (원화) 일백만이십삼만사천오백칠십팔

--- - 참고 링크

  1. 나머지 연산
    https://dongdongfather.tistory.com/18
  1. 뒤에서부터 자르기
    https://sixthgo.tistory.com/entry/%EC%98%A4%EB%9D%BC%ED%81%B4-%EB%AC%B8%EC%9E%90%EC%97%B4-%ED%95%A8%EC%88%98-%EC%A0%95%EB%A6%AC
  1. for문
    https://m.blog.naver.com/PostView.nhn?blogId=oasis1570&logNo=40130654749&proxyReferer=http%3A%2F%2Fwww.google.com%2Furl%3Fsa%3Dt%26rct%3Dj%26q%3D%26esrc%3Ds%26source%3Dweb%26cd%3D2%26ved%3D2ahUKEwihl5D738_lAhXFQN4KHXOdDScQFjABegQIAhAB%26url%3Dhttp%253A%252F%252Fm.blog.naver.com%252Foasis1570%252F40130654749%26usg%3DAOvVaw2kiWI17gM39t8pkK2pUGCy

  2. 올림함수
    https://dongdongfather.tistory.com/17

  1. 내가 하려는 것
    https://fly32.net/249
  1. 함수 create, 실행 HOW TO
    https://lee-mandu.tistory.com/59

- 코드

CREATE OR REPLACE FUNCTION 메롱."SJ_TEST_FNC"(divide VARCHAR, num_input NUMBER)
    RETURN VARCHAR
IS
    krw_name VARCHAR(100);     --숫자를 한글로 OUTPUT
    num_template VARCHAR(100); --구분자로 나뉘어진 OUTPUT

    dividing VARCHAR(2);       --구분자
    num_char VARCHAR(100);     --입력된 숫자를 CHAR형으로 변환
    num_length NUMBER;         --자리수

    is_zero VARCHAR(1);        --0인지 체크(Y/N)

    four_length NUMBER;        --4로 나눈 개수 (단위 계산을 위함)
    four_mod NUMBER;           --4로 나눈 나머지
    cut_four NUMBER;           --4로 나눈 값. 
    num_four VARCHAR(4);       --4글자로 자른 값
    num_one VARCHAR(1);        --1글자로 자른 값

BEGIN
    dividing := divide; 
    num_char := TO_CHAR(num_input);
    num_length := LENGTH(num_char); 
    cut_four := CEIL(num_length/4); --올림 안 하면 (소수점일 경우) IF문 못 들어감
    four_mod := MOD(num_length,4); 

    --구분자 처리 부분
    --뒤에서부터 3단위로 쪼개기
    FOR i IN 1..CEIL(num_length/3)
    LOOP
        num_template := SUBSTR(num_char,-(3*i),3)||dividing||num_template; 
    END LOOP;

    -- 3으로 나누어 떨어지지 않는 부분은 FOR문 나와서 처리
    num_template := SUBSTR(num_char,1,MOD(num_length,3))||num_template;  
    num_template := RTRIM(num_template,dividing);


    --숫자를 한글로, 처리 부분
    --4개가 한 세트. 몇 세트 FOR문 도는지
    FOR i IN 1..cut_four 
    LOOP
        num_four := '';
        IF four_mod != 0 AND i = 1 THEN
            four_length := four_mod;
        ELSE
            four_length := 4;
        END IF;

        --4번 FOR문 도는지 or 그 이하로 도는지
        FOR j IN 1..four_length  
        LOOP                   
            IF i= 1 THEN
                num_one := SUBSTR(num_char, j, 1);
            ELSIF four_mod = 0 THEN
                num_one := SUBSTR(num_char, (i-2)*4 + (four_mod+j) + 4, 1);
            ELSE
                num_one := SUBSTR(num_char, (i-2)*4 + (four_mod+j), 1);
            END IF;

            num_four := num_four || num_one;

            --한자리씩 한글로 변환
            IF num_one = '0' THEN 
                is_zero := 'Y';  
            ELSE  
                is_zero := 'N';   
                IF num_one = '1' THEN
                    krw_name := krw_name||'일';
                ELSIF num_one = '2' THEN
                    krw_name := krw_name||'이';
                ELSIF num_one = '3' THEN
                    krw_name := krw_name||'삼';       
                ELSIF num_one = '4' THEN
                    krw_name := krw_name||'사'; 
                ELSIF num_one = '5' THEN
                    krw_name := krw_name||'오'; 
                ELSIF num_one = '6' THEN
                    krw_name := krw_name||'육'; 
                ELSIF num_one = '7' THEN
                    krw_name := krw_name||'칠'; 
                ELSIF num_one = '8' THEN
                    krw_name := krw_name||'팔'; 
                ELSIF num_one = '9' THEN
                    krw_name := krw_name||'구';
                END IF;
            END IF;

            --단위 변환 (안쪽 FOR문 끝남)
            IF is_zero = 'N' THEN 
                IF four_length-j = 3 THEN
                    krw_name := krw_name || '천';
                ELSIF four_length-j = 2 THEN
                    krw_name := krw_name || '백';
                ELSIF four_length-j = 1 THEN
                    krw_name := krw_name || '십';
                END IF;
            END IF;

        END LOOP;

        --단위 변환 (바깥쪽 FOR문 끝남)
        IF num_four != '0000' THEN 
            IF cut_four-i = 4 THEN
                krw_name := krw_name || '경 ';
            ELSIF cut_four-i = 3 THEN
                krw_name := krw_name || '조 ';
            ELSIF cut_four-i = 2 THEN
                krw_name := krw_name || '억 ';
            ELSIF cut_four-i = 1 THEN
                krw_name := krw_name || '만 ';
            END IF;
        END IF;

    END LOOP;

RETURN num_template||' = '||krw_name||'원';

EXCEPTION WHEN OTHERS THEN
    RETURN NULL;
END;

  • if-else문

https://thebook.io/006696/part02/ch09/01/01/

<조건이 1개일 경우>
    IF 조건 THEN
       조건 처리;
    END IF;

<조건이 2개일 경우>
    IF 조건 THEN
       조건 처리 1;
    ELSE
      조건 처리2;
    END IF;

<조건이 n개일 경우>
    IF 조건1 THEN
       조건 처리1;
    ELSIF 조건2 THEN
      조건 처리2;
      ...
    ELSE
       조건 처리n;
    END IF;

  • for문. <2가지 방법>

FOR ~ LOOP ~ END LOOP : 그때그때 선언

FOR 인덱스 IN 초기값..최종값
LOOP
    처리문;
END LOOP;

CURSOR ~ FETCH: 반복이 많을 때, cursor에 선언만 미리 해놓고 fetch에서 loop도는

CURSOR 커서이름 IS
    SELECT 처리문;

http://www.gurubee.net/lecture/1064

cursor, fetch 예제

CURSOR c8 IS

       SELECT 처리문 ~~

       ;

     BEGIN

       -- 커서의 오픈
       OPEN c8;
            LOOP

            -- 커서의 패치 
            FETCH c8

            INTO ~~

            EXIT WHEN ~~

            END LOOP;

       -- 커서의 CLOSE
       CLOSE c8;      

    EXCEPTION
      WHEN OTHERS THEN
        DBMS_OUTPUT.PUT_LINE(SQLERRM||'에러 발생 ');

   END;

  • 변수명 작성 시

INPUT은 in_

OUTPUT은 out_

내부에서 쓰이는 변수는 v_


  • 시퀀스.CURRVAL, 시퀀스.NEXTVAL

사용시 주의사항 : https://mine-it-record.tistory.com/62

SELECT testSeq.NEXTVAL FROM DUAL; -- 해당 시퀀스의 다음값

SELECT testSeq.CURRVAL FROM DUAL; -- 해당 시퀀스의 현재값

INSERT INTO oracleStudy VALUES(testSeq.NEXTVAL, 'studyName' , 'class' , A); --INSERT에서의 시퀀스 다음값

  • 컬럼값은 대문자, 변수는 소문자

Comments