본문 바로가기

DB/Oracle

오라클 한글 초성 검색 방법 , DB 초중종성 검색 방법 - 삽질중인 개발자

반응형

- 오라클에서 한글 초중종성 검색 방법 -

 

오라클에서 한글 초중종성 검색을 구현하는 방법이다.

함수를 사용한 방법으로 초성, 중성, 종성의 문자를 추출하여 비교하는 방식이다.

가장 베스트 방법은 처음부터 검색될 단어의 초성을 저장하고 있는 것이지만 DB 구조가 그렇지 않다면 아래와 같은 방식으로 구현한다.

아래의 함수에서 약간 수정하면 초성용 함수도 만들 수 있다. 

 

 

1. 한글을 초중종성으로 나눠주는 FUNCTION 생성

 

아래의 초성을 나누는 함수를 살짝 수정해서 원하는 방식으로 구현하면 됩니다.

CREATE OR REPLACE FUNCTION FN_GET_KOREA_SYLLABLE (
    i_p1    IN    VARCHAR2
)
    RETURN VARCHAR2
AS
    l_rt    VARCHAR2 (4000);
 
 
    FUNCTION f1 (
        i_p1    IN    VARCHAR2
    )
        RETURN VARCHAR2
    AS
        l_p1    PLS_INTEGER     := ASCII (UNISTR (i_p1));
        l_i0    PLS_INTEGER     := l_p1 - TO_NUMBER ('AC00', 'XXXX');
        l_i1    PLS_INTEGER     := TO_NUMBER ('1100', 'XXXX') + FLOOR (l_i0 / (21 * 28));
        l_i2    PLS_INTEGER     := TO_NUMBER ('1161', 'XXXX') + FLOOR (MOD (l_i0, (21 * 28)) / 28);
        l_i3    PLS_INTEGER     := TO_NUMBER ('11A7', 'XXXX') + FLOOR (MOD (l_i0, 28));
        l_rt    VARCHAR2(4000);
    BEGIN
        CASE
            WHEN l_p1 BETWEEN TO_NUMBER ('AC00', 'XXXX') AND TO_NUMBER ('D7A3', 'XXXX')
            THEN
                l_rt := NCHR (l_i1)
                     || CASE WHEN l_i2 <> 4519 THEN NCHR (l_i2) END
                     || CASE WHEN l_i3 <> 4519 THEN NCHR (l_i3) END
                     ;
            ELSE
                l_rt := i_p1;
        END CASE;
 
        RETURN l_rt;
    END f1;
 
 
    FUNCTION f2 (
        i_p1    IN    VARCHAR2
    )
        RETURN VARCHAR2
    AS
        l_p1    VARCHAR2(10);
        l_rt    VARCHAR2(30);
    BEGIN
 
        FOR i IN 1.. LENGTH( i_p1 )
        LOOP
        
            l_p1 := SUBSTR(i_p1, i, 1);
        
            IF l_p1 = 'ᆨ' OR l_p1 = 'ᄀ' THEN l_p1 := 'ㄱ';
            ELSIF l_p1 = 'ᆫ' OR l_p1 = 'ᄂ' THEN l_p1 := 'ㄴ';
            ELSIF l_p1 = 'ᆮ' OR l_p1 = 'ᄃ' THEN l_p1 := 'ㄷ';
            ELSIF l_p1 = 'ᆯ' OR l_p1 = 'ᄅ' THEN l_p1 := 'ㄹ';
            ELSIF l_p1 = 'ᆷ' OR l_p1 = 'ᄆ' THEN l_p1 := 'ㅁ';
            ELSIF l_p1 = 'ᆸ' OR l_p1 = 'ᄇ' THEN l_p1 := 'ㅂ';
            ELSIF l_p1 = 'ᆺ' OR l_p1 = 'ᄉ' THEN l_p1 := 'ㅅ';
            ELSIF l_p1 = 'ᆼ' OR l_p1 = 'ᄋ' THEN l_p1 := 'ㅇ';
            ELSIF l_p1 = 'ᆽ' OR l_p1 = 'ᄌ' THEN l_p1 := 'ㅈ';
            ELSIF l_p1 = 'ᆾ' OR l_p1 = 'ᄎ' THEN l_p1 := 'ㅊ';
            ELSIF l_p1 = 'ᆿ' OR l_p1 = 'ᄏ' THEN l_p1 := 'ㅋ';
            ELSIF l_p1 = 'ᇀ' OR l_p1 = 'ᄐ' THEN l_p1 := 'ㅌ';
            ELSIF l_p1 = 'ᇁ' OR l_p1 = 'ᄑ' THEN l_p1 := 'ㅍ';
            ELSIF l_p1 = 'ᇂ' OR l_p1 = 'ᄒ' THEN l_p1 := 'ㅎ';
            ELSIF l_p1 = 'ᆩ' OR l_p1 = 'ᄁ' THEN l_p1 := 'ㄲ';
            ELSIF l_p1 = 'ᄄ' THEN l_p1 := 'ㄸ';
            ELSIF l_p1 = 'ᄈ' THEN l_p1 := 'ㅃ';
            ELSIF l_p1 = 'ᄊ' OR l_p1 = 'ᆻ' THEN l_p1 := 'ㅆ';
            ELSIF l_p1 = 'ᄍ' THEN l_p1 := 'ㅉ';
            ELSIF l_p1 = 'ᆪ' THEN l_p1 := 'ᄀᄉ';
            ELSIF l_p1 = 'ᆬ' THEN l_p1 := 'ᄂᄌ';
            ELSIF l_p1 = 'ᆭ' THEN l_p1 := 'ᄂᄒ';
            ELSIF l_p1 = 'ᆰ' THEN l_p1 := 'ᄅᄀ';
            ELSIF l_p1 = 'ᆱ' THEN l_p1 := 'ᄅᄆ';
            ELSIF l_p1 = 'ᆲ' THEN l_p1 := 'ᄅᄇ';
            ELSIF l_p1 = 'ᆳ' THEN l_p1 := 'ᄅᄉ';
            ELSIF l_p1 = 'ᆴ' THEN l_p1 := 'ᄅᄐ';
            ELSIF l_p1 = 'ᆶ' THEN l_p1 := 'ᄅᄒ';
            ELSIF l_p1 = 'ᆹ' THEN l_p1 := 'ᄇᄉ';
            ELSIF l_p1 = 'ᅡ' THEN l_p1 := 'ㅏ';
            ELSIF l_p1 = 'ᅣ' THEN l_p1 := 'ㅑ';
            ELSIF l_p1 = 'ᅥ' THEN l_p1 := 'ㅓ';
            ELSIF l_p1 = 'ᅧ' THEN l_p1 := 'ㅕ';
            ELSIF l_p1 = 'ᅩ' THEN l_p1 := 'ㅗ';
            ELSIF l_p1 = 'ㅛ' THEN l_p1 := 'ㅛ';
            ELSIF l_p1 = 'ᅮ' THEN l_p1 := 'ㅜ';
            ELSIF l_p1 = 'ᅲ' THEN l_p1 := 'ㅠ';
            ELSIF l_p1 = 'ᅳ' THEN l_p1 := 'ㅡ';
            ELSIF l_p1 = 'ᅵ' THEN l_p1 := 'ㅣ';
            ELSIF l_p1 = 'ᅢ' THEN l_p1 := 'ㅐ';
            ELSIF l_p1 = 'ᅤ' THEN l_p1 := 'ㅒ';
            ELSIF l_p1 = 'ᅦ' THEN l_p1 := 'ㅔ';
            ELSIF l_p1 = 'ᅨ' THEN l_p1 := 'ㅖ';
            ELSIF l_p1 = 'ᅬ' THEN l_p1 := 'ㅚ';
            ELSIF l_p1 = 'ᅱ' THEN l_p1 := 'ㅟ';
            ELSIF l_p1 = 'ᅴ' THEN l_p1 := 'ㅢ';
            ELSIF l_p1 = ' ' THEN l_p1 := '';
            END IF;
            
            l_rt := l_rt || l_p1;
        
        END LOOP;
 
        RETURN l_rt;
    END f2;
 
 
BEGIN
 
    FOR i IN 1..LENGTH( i_p1 )
    LOOP
        l_rt := l_rt || f2( f1( SUBSTR(i_p1, i, 1) ) );
    END LOOP;
 
    RETURN l_rt;
END FN_GET_KOREA_SYLLABLE;

 

 

2. 사용방법

SELECT * FROM t_word WHERE FN_GET_KOREA_SYLLABLE(word) LIKE FN_GET_KOREA_SYLLABLE('%김%')

 

3. 주의사항

위의 방법을 사용해서 WHERE 절에 초성을 검색하는 방법은 모든 단어를 분리해야해 DB에 부담이 큰 방법이다. 

따라서 적은 양의 데이터를 초성 검색하기에는 좋은 방법이지만 데이터가 많아지면 DB에 초성 전용 컬럼을 하나 만들어서 그 컬럼과 비교하는 방법을 추천한다. 

 

 

 


 

javascript로 한글 초성 검색 구현하는 방법

 

 

검색어 자동완성 - jQuery Autocomplete 한글 초성 검색 1 - 개발자 삽질 일기

-jQuery Autocomplete 한글 초성 검색- jQuery UI의 autocomplete 는 영어대한 검색은 잘된다. but, 한글의 경우 초성만 입력했을 때 자동완성이 안된다. 한글 초성검색을 구현하는 방법중에는 DB에서부터 초성검..

programmer93.tistory.com

 

반응형