기본 콘텐츠로 건너뛰기

Oracle PL/SQL로 한글 초성 검색 구현하기: FN_CHOSEARCH · FN_APARTCHR 완전 정리

2. 한글 초·중·종성 분리 함수: FN_APARTCHR

초성 검색을 넘어, 한글 한 글자를 초성·중성·종성 단위로 완전히 분리해야 할 때가 있습니다. 예를 들어 '각''ㄱㅏㄱ'으로 분해하여 형태소 분석이나 유사도 검사에 활용하는 경우입니다.

이 로직은 한글 유니코드의 구성 원리를 기반으로 합니다.

2.1 핵심 분해 함수: FN_APARTCHR

아래 함수는 입력된 한 글자가 한글 완성형 범위(AC00 ~ D7A3)에 속하는지 확인한 후, 유니코드 공식을 적용하여 자모를 분리합니다.

CREATE OR REPLACE FUNCTION FN_APARTCHR(P_CHAR IN VARCHAR2)
RETURN VARCHAR2
IS
    ExceptNoHangul EXCEPTION;
    startHanUniDec NUMBER;
    calHanUniDec   NUMBER;
    tmpUniDec      NUMBER;
    initUniDec     NUMBER;
    vowelUniDec    NUMBER;
    finUniDec      NUMBER;
    initStr        VARCHAR2(10);
    vowelStr       VARCHAR2(10);
    finStr         VARCHAR2(10);
BEGIN
    -- 한글 완성형 범위(AC00 ~ D7A3) 확인
    IF ASCIISTR(P_CHAR) NOT BETWEEN '\AC00' AND '\D7A3' THEN
        RETURN P_CHAR; -- 한글 아니면 원문 반환
    END IF;

    startHanUniDec := FN_HEX_TO_DEC('AC00');        -- '가' 유니코드
    calHanUniDec   := FN_HEX_TO_DEC(REPLACE(ASCIISTR(P_CHAR), '\', '')); 
    tmpUniDec      := calHanUniDec - startHanUniDec;

    -- 초성 계산 (588 = 21 * 28)
    initUniDec := FLOOR(tmpUniDec/588) + FN_HEX_TO_DEC('1100');
    initStr    := UNISTR('\' || FN_DEC_TO_HEX(initUniDec));

    -- 중성 계산
    vowelUniDec := FLOOR(MOD(tmpUniDec, 588) / 28) + FN_HEX_TO_DEC('1161');
    vowelStr    := UNISTR('\' || FN_DEC_TO_HEX(vowelUniDec));

    -- 종성 계산
    finUniDec := MOD(MOD(tmpUniDec, 588), 28) + FN_HEX_TO_DEC('11A8') - 1;

    IF MOD(MOD(tmpUniDec, 588), 28) = 0 THEN
        finStr := NULL; 
    ELSE
        finStr := UNISTR('\' || FN_DEC_TO_HEX(finUniDec));
    END IF;

    RETURN initStr || vowelStr || finStr;
EXCEPTION
    WHEN OTHERS THEN RETURN 'ERROR:' || SQLERRM;
END;
⚠️ 주의사항:
위 코드가 정상 동작하려면 16진수 변환을 담당하는 FN_DEC_TO_HEXFN_HEX_TO_DEC 보조 함수가 먼저 생성되어 있어야 합니다. (이전 섹션을 참고하세요.)

2.2 문자열 전체 분해: FN_GET_DIV_KO_CHAR

마지막으로, 문자열 전체를 루프(Loop) 돌며 변환하는 래퍼 함수입니다.

CREATE OR REPLACE FUNCTION FN_GET_DIV_KO_CHAR(i_p1 IN VARCHAR2)
RETURN VARCHAR2
AS
    l_rt VARCHAR2(4000);
BEGIN
    FOR i IN 1 .. LENGTH(i_p1) LOOP
        l_rt := l_rt || FN_APARTCHR(SUBSTR(i_p1, i, 1));
    END LOOP;
    RETURN l_rt;
END;

댓글

이 블로그의 인기 게시물

Java Servlet Request Parameter 완전 정복 — GET/POST 모든 파라미터 확인 & 디버깅 예제 (Request Parameter 전체보기)

Java Servlet Request Parameter 완전 정복 — GET/POST 모든 파라미터 확인 & 디버깅 예제 Java Servlet Request Parameter 완전 정복 웹 애플리케이션에서 클라이언트로부터 전달되는 Request Parameter 를 확인하는 것은 필수입니다. 이 글에서는 Java Servlet 과 JSP 에서 GET/POST 요청 파라미터를 전체 출력하고 디버깅하는 방법을 다양한 예제와 함께 소개합니다. 1. 기본 예제: getParameterNames() 사용 Enumeration<String> params = request.getParameterNames(); System.out.println("----------------------------"); while (params.hasMoreElements()){ String name = params.nextElement(); System.out.println(name + " : " + request.getParameter(name)); } System.out.println("----------------------------"); 위 코드는 요청에 포함된 모든 파라미터 이름과 값을 출력하는 기본 방법입니다. 2. HTML Form과 연동 예제 <form action="CheckParamsServlet" method="post"> 이름: <input type="text" name="username"><br> 이메일: <input type="email" name="email"><b...

PostgreSQL 달력(일별,월별)

SQL 팁: GENERATE_SERIES로 일별, 월별 날짜 목록 만들기 SQL 팁: GENERATE_SERIES 로 일별, 월별 날짜 목록 만들기 데이터베이스에서 통계 리포트를 작성하거나 비어있는 날짜 데이터를 채워야 할 때, 특정 기간의 날짜 목록이 필요할 수 있습니다. PostgreSQL과 같은 데이터베이스에서는 GENERATE_SERIES 함수를 사용하여 이 작업을 매우 간단하게 처리할 수 있습니다. 1. 🗓️ 일별 날짜 목록 생성하기 2020년 1월 1일부터 12월 31일까지의 모든 날짜를 '1 day' 간격으로 생성하는 쿼리입니다. WITH date_series AS ( SELECT DATE(GENERATE_SERIES( TO_DATE('2020-01-01', 'YYYY-MM-DD'), TO_DATE('2020-12-31', 'YYYY-MM-DD'), '1 day' )) AS DATE ) SELECT DATE FROM date_series 이 쿼리는 WITH 절(CTE)을 사용하여 date_series 라는 임시 테이블을 만들고, GENERATE_SERIES 함수로 날짜를 채웁니다. 결과 (일별 출력) 2. 📅 월별 날짜 목록 생성하기 동일한 원리로, 간격을 '1 MONTH' 로 변경하면 월별 목록을 생성할 수 있습니다. TO...

CSS로 레이어 팝업 화면 가운데 정렬하는 방법 (top·left·transform 완전 정리)

레이어 팝업 센터 정렬, 이 코드만 알면 끝 (CSS 예제 포함) 이벤트 배너나 공지사항을 띄울 때 레이어 팝업(center 정렬) 을 깔끔하게 잡는 게 생각보다 어렵습니다. 화면 크기가 변해도 가운데에 고정되고, 모바일에서도 자연스럽게 보이게 하려면 position , top , left , transform 을 정확하게 이해해야 합니다. 이 글에서는 아래 내용을 예제로 정리합니다. 레이어 팝업(center 정렬)의 기본 개념 자주 사용하는 position: absolute / fixed 정렬 방식 질문에서 주신 스타일 top: 3.25%; left: 50%; transform: translateX(-50%) 의 의미 실무에서 바로 쓰는 반응형 레이어 팝업 HTML/CSS 예제 1. 레이어 팝업(center 정렬)이란? 레이어 팝업(레이어 팝업창) 은 새 창을 띄우는 것이 아니라, 현재 페이지 위에 div 레이어를 띄워서 공지사항, 광고, 이벤트 등을 보여주는 방식을 말합니다. 검색엔진(SEO) 입장에서도 같은 페이지 안에 HTML이 존재 하기 때문에 팝업 안의 텍스트도 정상적으로 인덱싱될 수 있습니다. 즉, “레이어 팝업 센터 정렬”, “레이어 팝업 만드는 방법”과 같이 관련 키워드를 적절히 넣어주면 검색 노출에 도움이 됩니다. 2. 질문에서 주신 레이어 팝업 스타일 분석 질문에서 주신 스타일은 다음과 같습니다. <div class="layer-popup" style="width:1210px; z-index:9001; position:absolute; top:3.25%; left:50%; transform:translateX(-50%);"> 레이어 팝업 내용 <...