FreeTDS 라이브러리를 이용하여 프로그램을 개발하여 테스트를 진행하는데, 테스트에 사용되던 MSSQL 서버에 문제가 생겨서 어느날부터 연결이 안되는 일이 발생했습니다. 여러 DBMS 에 연결하는 프로그램이었는데, 항상 잘 돌아가던 서버여서 당연히 연결될꺼라는 과정으로 프로그램을 코딩하는 바람에 서버에 연결안되는 순간부터 "FreeTDS: db-lib: exiting because client error handler returned 0 for msgno 20009" 에러가 나면서 메인 프로그램을 kill 시키는 것입니다.
서버에 연결실패할 경우 dbopen() 의 return 값인 dbproc 가 NULL 이 되어 에러메시지를 출력하고 return 할 것으로 예상했지만, 전체 프로그램이 kill 되면서 20009 메시지가 나옵니다.
이유를 찾아보니, 20009 메시지는 "서버에 연결할 수 없다" 라는 것입니다. (include/sybdb.h) 그리고, 에러가 나면 default 로 프로세스를 kill 시킨다고 합니다.if ((dbproc = dbopen(login, options.servername)) == NULL) { fprintf(stderr, "%s:%d: unable to connect to %s as %s\n", options.appname, __LINE__, options.servername, options.username); return; }
해결방법은 의외로 간단합니다. dbinit() 함수 다음에 와 message 핸들러와 error 핸들러를 등록하는데, error 핸들러의 return 값을 "INT_CANCEL" 로 변경합니다. ("0" 은 "INT_EXIT" 입니다.)
int
msg_handler(DBPROCESS *dbproc, DBINT msgno, int msgstate, int severity,
char *msgtext, char *srvname, char *procname, int line)
{
enum {changed_database = 5701, changed_language = 5703 };
if (msgno == changed_database || msgno == changed_language)
return 0;
if (msgno > 0) {
fprintf(stderr, "Msg %ld, Level %d, State %d\n",
(long) msgno, severity, msgstate);
if (strlen(srvname) > 0)
fprintf(stderr, "Server '%s', ", srvname);
if (strlen(procname) > 0)
fprintf(stderr, "Procedure '%s', ", procname);
if (line > 0)
fprintf(stderr, "Line %d", line);
fprintf(stderr, "\n\t");
}
fprintf(stderr, "%s\n", msgtext);
if (severity > 10) {
fprintf(stderr, "%s: error: severity %d > 10, exiting\n",
options.appname, severity);
exit(severity);
}
return 0;
}
int
err_handler(DBPROCESS * dbproc, int severity, int dberr, int oserr,
char *dberrstr, char *oserrstr)
{
if (dberr) {
fprintf(stderr, "%s: Msg %d, Level %d\n",
options.appname, dberr, severity);
fprintf(stderr, "%s\n\n", dberrstr);
}
else {
fprintf(stderr, "%s: DB-LIBRARY error:\n\t", options.appname);
fprintf(stderr, "%s\n", dberrstr);
}
return INT_CANCEL;
}
출처 :
http://blog.gmane.org/gmane.comp.db.tds.freetds/month=20100106
http://www.freetds.org/userguide/samplecode.htm#SAMPLECODE.ERRORS.
'Engineering > DB' 카테고리의 다른 글
mysql prepared statement API 프로그래밍 시 time 필드 처리 (0) | 2012.12.10 |
---|---|
MySQL 에서 테이블 스키마만 가져오려고 하는 경우 (0) | 2011.09.27 |
MySQL UTF-8 지원 설정 (0) | 2011.07.18 |
db2 라이브러리를 포함한 프로그램 make 시 에러 발생 (0) | 2011.07.05 |
MySQL 설치후 암호 설정 및 사용자 추가 (0) | 2011.05.27 |