기술 정보
home
채널 소개
home

내장 SQL (Embedded SQL) multi thread 실행 방법

문서 유형
기술 정보
분야
튜닝
키워드
Embedded SQL
multi thread
1 more property

개요

multi thread에서 안전하게 내장 SQL (Embedded SQL, ESQL)을 실행하는 방법을 안내합니다.
내장 SQL (Embedded SQL) 을 멀티스레드 환경에서 실행하려면 컴파일 시 옵션과 소스 코드 내 설정이 필요합니다. 이를 통해 여러 스레드에서 안전하게 ESQL을 사용할 수 있습니다.

방법

내장 SQL (Embedded SQL, ESQL) 을 멀티스레드 환경에서 실행하려면 esql precompile 옵션에 THREADS=YES 추가해서 컴파일해야 합니다.
또한 소스 코드에는 EXEC SQL ENABLE THREADS; EXEC SQL CONTEXT USE DEFAULT;를 설정해야합니다.

예제 코드 1

#include <stdio.h> #include <string.h> void esql_error(int line_no, int err_no, char *file) { printf("esql test esql_error at %d : %d in %s\n", line_no, err_no, file); } void main(void) { char *uid = "tibero"; char *pwd = "tmax"; int balance = 0; sql_context ctx1; sql_context ctx2; printf("***** thread context test start *****\n\n"); EXEC SQL WHENEVER SQLERROR DO esql_error(__LINE__, sqlca.sqlcode, __FILE__); EXEC SQL ENABLE THREADS; EXEC SQL CONTEXT USE DEFAULT; EXEC SQL CONNECT :uid IDENTIFIED BY :pwd; EXEC SQL WHENEVER SQLERROR continue; EXEC SQL DROP TABLE ACCOUNT; EXEC SQL CREATE TABLE ACCOUNT ( ACCOUNT_ID CHAR(14), BRANCH_CD CHAR(4), CUSTOMER_ID CHAR(13), ACCOUNT_TYPE CHAR(4), BALANCE NUMBER(15, 5), CREATE_DATE DATE, EXPIRY_DATE DATE ); EXEC SQL WHENEVER SQLERROR DO esql_error(__LINE__, sqlca.sqlcode, __FILE__); EXEC SQL INSERT INTO account VALUES ('ACCOUNT_ID_001', 'B003', 'CUSTOMER_ID_0', 'A002', 500000, '2003-10-5', '2005-10-5'); EXEC SQL INSERT INTO account VALUES ('ACCOUNT_ID_002', 'B003', 'CUSTOMER_ID_1', 'A001', 10000, '2003-12-25', '2010-12-25'); EXEC SQL INSERT INTO account VALUES ('ACCOUNT_ID_003', 'B001', 'CUSTOMER_ID_2', 'A003', 50000000, '1998-9-1', '2005-9-1'); EXEC SQL COMMIT WORK; EXEC SQL CONTEXT ALLOCATE :ctx1; EXEC SQL CONTEXT ALLOCATE :ctx2; EXEC SQL CONTEXT USE :ctx1; EXEC SQL CONNECT :uid IDENTIFIED BY :pwd; EXEC SQL SELECT BALANCE INTO :balance FROM ACCOUNT WHERE ACCOUNT_ID = 'ACCOUNT_ID_001'; if (balance != 500000) printf("expected : 500000, real : %d\n", balance); EXEC SQL CONTEXT USE :ctx2; EXEC SQL CONNECT :uid IDENTIFIED BY :pwd; EXEC SQL SELECT BALANCE INTO :balance FROM ACCOUNT WHERE ACCOUNT_ID = 'ACCOUNT_ID_002'; if (balance != 10000) printf("expected : 10000, real : %d\n", balance); EXEC SQL CONTEXT FREE :ctx1; EXEC SQL CONTEXT FREE :ctx2; EXEC SQL CONTEXT USE DEFAULT; EXEC SQL SELECT BALANCE INTO :balance FROM ACCOUNT WHERE ACCOUNT_ID = 'ACCOUNT_ID_002'; if (balance != 10000) printf("expected : 10000, real : %d\n", balance); printf("***** thread context test end *****\n"); }
SQL
복사

예제 코드 2

int Fn_DRFT_SYNC_Make_LoadFile(char *p_exp_type) { FRM_ERR("=========LOAD START=========="); char s_load_path [ 255+1]; char s_load_msg [ 255+1]; char s_file_type [ 3+1]; char s_exp_type [ 1+1]; //EXPORT 대상 TABLE 구분 char *conn_str = "msscm/msscm"; SQLRETURN n_ret = SQL_SUCCESS; SQLINTEGER versionNumber = 1; SQLCHAR dataFileName[256]; SQLCHAR actionString[256]; SQLCHAR msgFileName[256]; SQLCHAR fieldTerm[5]; SQLCHAR lineTerm[5]; SQLCHAR enclStart[5]; SQLCHAR enclEnd[5]; struct sqlca ca = {"\0", 0, 0, {0, "\0"}, "\0", {0, 0, 0, 0, 0, 0}, "\0", "\0"}; FRM_ERR("=========LOAD 1=========="); TBExportStruct exportStruct = {NULL, 0, NULL, NULL, NULL, 0, NULL, 0, NULL, NULL}; TBExportIn exportIn = {{NULL, 0, NULL, 0, NULL, 0, NULL, 0, NULL, 0}}; TBExportOut exportOut = {0}; EXEC SQL ENABLE THREADS; EXEC SQL CONTEXT USE DEFAULT; EXEC SQL CONNECT :conn_str; n_ret = TBConnect((SQLCHAR *)DNS_NAME, (SQLCHAR *)USER_NAME, (SQLCHAR *)PWD, &ca); if(n_ret != SQL_SUCCESS) return -1; //EXPORT 할 대상 TABLE 구분 - D:DATA 테이블, S:SUM 테이블 memset (s_exp_type , 0x00 , sizeof(s_exp_type)); strcpy (s_exp_type , p_exp_type); //EXPORT FILE TYPE 정의 - DEL타입 강제 세팅 //memset (s_file_type , 0x00 , sizeof(s_file_type)); //memcpy (s_file_type , "DEL" , sizeof(s_file_type)-1); FRM_ERR("=========LOAD 2=========="); //EXPORT SQL 세팅 memset (g_export_sql, 0x00 , sizeof(g_export_sql )); sprintf(g_export_sql, "SELECT * FROM %s", g_GLB_TABLE); if ( s_exp_type[0] == 'D' ) { //EXPORT DATA FILE PATH 설정 memset (s_load_path, 0x00, sizeof( s_load_path ) ); sprintf(s_load_path, "%s/%.4s%.8s_%.2s.DEL", DRFT_LOAD_PATH , g_orgcode, g_sysdate, g_sync_seq ); //EXPORT MSG PATH 설정 memset (s_load_msg , 0x00, sizeof( s_load_msg ) ); sprintf(s_load_msg , "%s/%.4s%.8s_%.2s.MSG", DRFT_LOAD_PATH , g_orgcode, g_sysdate, g_sync_seq ); } else { //EXPORT FILE PATH 설정 memset (s_load_path, 0x00, sizeof( s_load_path ) ); sprintf(s_load_path, "%s/%.4s%.8s_SUM_%.2s.DEL", g_sysdate, g_sync_seq ); //EXPORT MSG PATH 설정 memset (s_load_msg , 0x00, sizeof( s_load_msg ) ); sprintf(s_load_msg , DRFT_LOAD_PATH , g_orgcode, "%s/%.4s%.8s_SUM_%.2s.MSG", DRFT_LOAD_PATH , g_orgcode, g_sysdate, g_sync_seq ); } strcpy((char *)dataFileName, s_load_path); strcpy((char *)actionString, g_export_sql); strcpy((char *)msgFileName, s_load_msg); strcpy((char *)fieldTerm, ","); strcpy((char *)lineTerm, "\n"); strcpy((char *)enclStart, "\""); strcpy((char *)enclEnd, "\""); FRM_ERR("=========LOAD 3=========="); /* setting data file name */ exportStruct.piDataFileName = dataFileName; exportStruct.iDataFileNameLen = strlen((char *)dataFileName); FRM_ERR("=========LOAD 4=========="); /* setting action String */ // exportStruct.piActionString = mfrm_cb_malloc(1024+sizeof(sqlstr)); exportStruct.piActionString = (struct sqlchar *)mfrm_cb_malloc( 1024 + sizeof( struct sqlchar)); exportStruct.piActionString->data = actionString; exportStruct.piActionString->length = strlen((char *)actionString); /* setting file type : s_file_type DEL 강제 설정 */ exportStruct.iFileType = SQL_DEL; FRM_ERR("=========LOAD 5=========="); /* setting message file name */ exportStruct.piMsgFileName = msgFileName; exportStruct.iMsgFileNameLen = strlen((char *)msgFileName); /* setting field term, line term etc.. SQL_METH_D에 따라 설정이 필요. */ exportIn.iMeta.fieldTerm = fieldTerm; exportIn.iMeta.fieldTermLen = strlen((char *)fieldTerm); exportIn.iMeta.lineTerm = lineTerm; exportIn.iMeta.lineTermLen = strlen((char *)lineTerm); exportIn.iMeta.enclStart = enclStart; exportIn.iMeta.enclStartLen = strlen((char *)enclStart); exportIn.iMeta.enclEnd = enclEnd; exportIn.iMeta.enclEndLen = strlen((char *)enclEnd); FRM_ERR("=========LOAD 6=========="); /* setting export input, output information */ exportStruct.piExportInfoIn = &exportIn; exportStruct.poExportInfoOut = &exportOut; FRM_ERR("=========LOAD 7=========="); FRM_ERR("n_ret : %d", n_ret); /* setting file type */ n_ret = TBExport(versionNumber, &exportStruct, &ca); FRM_ERR("=========LOAD 8=========="); if (n_ret != SQL_SUCCESS) { FRM_ERR("[%s]EXPORT ERROR!!![%d][%d]\n[%s]", s_load_path, n_ret, SQLCODE, g_export_sql ); g_sqlcode = SQLCODE; return -1; } FRM_ERR("=========LOAD 9=========="); FRM_DSP("[%.4s][%.8s][%.2s][ROWS EXPORT]:[%ld]", g_orgcode, g_sysdate, g_sync_seq, exportOut.oRowsExported ); /* disconnect */ n_ret = TBDisconnect((SQLCHAR *)DNS_NAME, &ca); if(n_ret != SQL_SUCCESS) return -1; EXEC SQL COMMIT WORK RELEASE; return 0; } =========================================================== EXEC SQL ENABLE THREADS; EXEC SQL CONTEXT USE DEFAULT; EXEC SQL CONNECT :"[userid]/[pw]";
SQL
복사