C External Procedure 유틸리티

사용자 공유 라이브러리 함수를 작성하는 데 유용한 C External Procedure 유틸리티를 설명 합니다.

C External Procedure에서는 사용자가 공유 라이브러리 함수를 구현하는 데 도움이 되는 몇 가지 API를 제공하고 있습니다. 이러한 API를 C External Procedure 유틸리티라고 합니다.

C External Procedure 유틸리티에 포함된 함수는 아래와 같습니다.

  • SQLExtProcAllocMemory

  • SQLExtProcRaiseError

  • SQLExtProcRaiseErrorWithMsg

이러한 함수를 사용하기 위해서는 Tibero에서 제공하는 ExtProcContext 구조체를 알아야 하며, 사용자가 공유 라이브러리를 작성할 때와 PSM으로 등록할 때 특별한 처리가 필요합니다.


C External Procedure 유틸리티 사용

C External Procedure 유틸리티를 사용하려면 tbEPA 프로세스에 이 유틸리티를 사용하겠다는 내용을 명시하고, 사용자 공유 라이브러리 또한 이 점을 감안하여 작성해야 합니다.

tbEPA 프로세스에 이러한 정보를 전달하기 위해서는 해당 사용자 공유 라이브러리 함수를 PSM으로 등록시킬 때 WITH CONTEXT 문법을 명시해야 하며, 사용자 공유 라이브러리 함수의 첫 번째 파라미터는 무조건 ExtProcContext *로 해야 합니다. ExtProcContext는 extproc.h 파일에 정의되어 있으며, tbEPA 프로세스에서 해당 C External Procedure 유틸리티 내의 함수를 처리해주는 채널로 사용합니다.

사용자 공유 라이브러리 함수 작성 시 유의 사항

Tibero는 사용자 공유 라이브러리 함수를 작성할 때 C External Procedure 유틸리티를 사용하는 경우를 대비하여 $TB_HOME/client/include 디렉터리에 있는 extproc.h 파일을 제공합니다. 만약 사용자가 작성할 공유 라이브러리 함수가 C External Procedure 유틸리티 내의 함수를 사용할 예정이라면 반드시 extproc.h 파일을 포함해야 합니다.

예를 들면 아래와 같습니다.

#include "extproc.h"

char * get_encrypted_string(ExtProcContext *epc, char *str)
{
  ...
}

사용자 공유 라이브러리 함수를 PSM으로 등록 시 유의 사항

사용자 함수를 PSM에 대응”을 보면 [WITH CONTEXT] 문법을 볼 수 있습니다. 이것이 바로 C External Procedure 유틸리티를 사용하고 있음을 DBMS에 알려주는 것이고, 이렇게 생성된 PSM을 수행할 경우에는 해당 정보를 tbEPA 프로세스에게 전달합니다.

그러면 tbEPA 프로세스는 해당 라이브러리를 로드하여 사용자 함수로 파라미터를 보낼 때 첫 번째 파라미터로 ExtProcContext의 포인터를 전달합니다.

CREATE OR REPLACE FUNCTION ext_get_enc_char (chr CHAR(10)) 
       RETURN CHAR
       AS LANGUAGE C
       LIBRARY extproc
       NAME "get_encrypted_string" 
       WITH CONTEXT
       PARAMETERS(CONTEXT, chr string);

위의 예처럼 PARAMETERS 문법을 명시할 경우 반드시 첫 번째 파라미터는 CONTEXT로 해야 합니다.


C External Procedure 유틸리티

본 절에서는 C External Procedure 유틸리티에서 제공하는 함수를 설명합니다.

SQLExtProcAllocMemory 함수

사용자가 작성한 공유 라이브러리 함수에서 동적으로 메모리 할당이 필요한 경우가 있습니다. 일반적으로 malloc, calloc 등의 함수를 사용하여 런타임 시 메모리를 할당받을 수 있으나, 만약 이 값을 반환 값 등으 로 사용할 경우 할당된 메모리를 해제하는 시점이 애매한 경우가 발생합니다.

이러한 문제를 해결하기 위해 C External Procedure 유틸리티에서는 SQLExtProcAllocMemory 함수를 제공합니다. 이 함수를 사용하면 사용자가 메모리를 동적으로 할당할 수 있으며, 할당된 메모리를 별도로 해제할 필요가 없습니다. 할당된 메모리는 해당 함수가 실행된 이후에 자동으로 해제됩니다.

SQLExtProcAllocMemory 함수의 세부 내용은 아래와 같습니다.

문법

SQLPOINTER SQLExtProcAllocMemory(ExtProcContext *, size_t size);

파라미터

파라미터

설명

ExtProcContext *

ExtProcContext 구조체의 포인터입니다.

size

할당받을 메모리의 크기입니다.

반환 값

성공여부

설명

성공

동적으로 할당한 메모리의 시작 주소를 반환합니다.

실패

NULL을 반환합니다.

예제

#include <string.h> 
#include "extproc.h" 
#include "sqlcli.h"

char * my_concat(ExtProcContext *epc, char *str1, char *str2)
{
    char *ret_str; 
    uint size;
    
    size = strlen(str1) + strlen(str2) + 1;
    ret_str = (char *) SQLExtProcAllocMemory(epc, size);
    
    strcpy(ret_str, str1); 
    strcat(ret_str, str2);
    
    return ret_str;
}

SQLExtProcRaiseError 함수

사용자 공유 라이브러리 함수를 수행하는 중에 에러가 발생하거나 에러를 발생시켜야 하는 경우 그 반환 값을 이용하여 PSM 내에서 에러 핸들링 과정을 구현할 수 있습니다. 단, 사용자가 원하는 로직을 구현하기 위 해서는 사용자 공유 라이브러리 함수뿐만 아니라 그 함수와 대응되는 PSM이 사용되는 모든 곳에 에러 핸들링 과정이 필요하다는 단점이 있습니다.

C External Procedure 유틸리티에서는 사용자 공유 라이브러리 함수에서 직접 DBMS 에러를 발생시켜 앞에서 언급한 단점을 해결할 수 있는 함수를 제공합니다.

이 함수를 이용하면 사용자 공유 라이브러리 함수 내에서 DIVIDE BY ZERO, NUMBER EXCEEDS PRECISION 등의 에러를 발생시킬 수 있습니다. 이러한 기능을 수행하는 함수가 바로 SQLExtProcRaiseError입니다.

이 함수는 Callback Service 에서도 사용할 수 있습니다.

SQLExtProcRaiseError 함수의 세부 내용은 아래와 같습니다.

문법

void SQLExtProcRaiseError(ExtProcContext *, int errcode);

파라미터

파라미터

설명

ExtProcContext *

ExtProcContext 구조체의 포인터입니다.

errcode

에러를 발생시킬 에러 코드의 번호입니다.

(에러 코드에 대한 자세한 내용은 "Tibero 에러 참조 안내서"를 참고)

예제

/* ExtProcContext *epc */
SQLExtProcRaiseErrorWithMsg(epc, 20100, "User exit procedure");

SQLExtProcRaiseErrorWithMsg 함수

SQLExtProcRaiseError 함수와 같이 에러를 발생시키는 함수입니다. 또한 사용자가 정의한 에러도 발생 시킬 수 있습니다.

SQLExtProcRaiseErrorWithMsg 함수의 세부 내용은 아래와 같습니다.

문법

void SQLExtProcRaiseErrorWithMsg(ExtProcContext *, int errcode, char *errmsg);

파라미터

파라미터

설명

ExtProcContext *

ExtProcContext 구조체의 포인터입니다.

errcode

사용자가 정의한 에러 코드(20000 ~ 20999)입니다.

*errmsg

사용자가 정의한 에러 메시지입니다.

예제

/* ExtProcContext *epc */
SQLExtProcRaiseErrorWithMsg(epc, 20100, "User exit procedure");

Last updated