/* ==================================================================== * ÆÄ ÀÏ : odbcsql.h * ¸ñ Àû : * ÀÛ ¼º ÀÚ : °ûöÁß * ÀÛ ¼º ÀÏ : 04/10/19 * ÁÖÀÇ»çÇ× : * =================================================================== */ #ifndef __ODBC_SQL_H__ #define __ODBC_SQL_H__ //#ifndef WINVER //#define WINVER 0x0500 //#endif // //#ifndef _WIN32_WINNT //#define _WIN32_WINNT 0x0500 //#endif #pragma once #include #include #include #include #include #include class cSQLConnection; class cSQLStatement; class cSQLEnvironment; // ÁÖÀÇ»çÇ× // 1. SQL_SUCCESS_WITH_INFO ¶Ç´Â SQL_ERROR ÀÏ °æ¿ì ·¹ÄÚµåÀÇ ³»¿ëÀ» È®ÀÎ ÇÒ ¼ö ÀÖ´Ù. // 2. Returns°ªÀÌ SQL_NO_DATAÀ϶§±îÁö È®ÀÎ È®Àΰ¡´É. // 3. Handle Type // SQL_HANDLE_ENV // SQL_HANDLE_DBC // SQL_HANDLE_STMT // SQL_HANDLE_DESC class cSQLDiag { friend class cSQLConnection; friend class cSQLStatement; friend class cSQLEnvironment; protected: SQLCHAR mSqlstate[ SQL_SQLSTATE_SIZE + 1 ]; SQLINTEGER mNativeErrorPtr; SQLCHAR mMessageText[ SQL_MAX_MESSAGE_LENGTH ]; public: cSQLDiag(void) {} virtual ~cSQLDiag(void) {} bool GetDiagRec( SQLSMALLINT handleType, SQLHANDLE handle, SQLSMALLINT recNumber=1 ) { SQLSMALLINT bufferLength = SQL_MAX_MESSAGE_LENGTH; SQLSMALLINT textLength = 0; SQLRETURN result = SQLGetDiagRec( handleType, handle, recNumber, // [IN ] Status records are numbered from 1. mSqlstate, // [OUT] SQL Error State string &mNativeErrorPtr, // [OUT] Native Error code mMessageText, // [OUT] SQL Error Text string bufferLength, // [IN ] Length of the *MessageText buffer in characters. &textLength ); return ( result == SQL_NO_DATA || result == SQL_ERROR ) ? false : true; } SQLCHAR* Sqlstate ( void ) { return mSqlstate; } SQLINTEGER NativeError ( void ) { return mNativeErrorPtr; } SQLCHAR* MessageText ( void ) { return mMessageText; } }; class cSQLEnvironment { friend class cSQLConnection; protected: // ȯ°æ ÇÚµé SQLHENV mHenv; public: cSQLEnvironment(void) : mHenv( SQL_NULL_HENV ) { } virtual ~cSQLEnvironment(void) { FreeEnv( ); } SQLHENV GetSqlEnv ( void ) { return mHenv; } // ȯ°æ ÇÚµéÀ» ÇÒ´çÇÑ´Ù. bool AllocEnv ( void ) { // SQLAllocHandle( SQL_HANDLE_ENV, SQL_NULL_HANDLE, &mHenv ) return (SQLAllocEnv( &mHenv ) == SQL_SUCCESS) ? true : false; } // ȯ°æ ÇÚµéÀ» ÇØÁ¦ÇÑ´Ù. void FreeEnv ( void ) { if ( mHenv != SQL_NULL_HENV ) { // SQLFreeHandle( SQL_HANDLE_ENV, mHenv ); SQLFreeEnv( mHenv ); mHenv = SQL_NULL_HENV; } } // ¿¬°á Ç®¸µÀ» ¼³Á¤ÇÑ´Ù. bool ConnectionPooling ( void ) { return (SQLSetEnvAttr( SQL_NULL_HENV, SQL_ATTR_CONNECTION_POOLING, (SQLPOINTER)SQL_CP_ONE_PER_DRIVER, SQL_IS_INTEGER ) == SQL_SUCCESS) ? true : false; } // ȯ°æ ¼Ó¼ºÀ» ¼³Á¤ÇÑ´Ù. bool SetEnvAttr ( SQLINTEGER Attribute = SQL_ATTR_ODBC_VERSION, SQLPOINTER ValuePtr = (SQLPOINTER)SQL_OV_ODBC3, SQLINTEGER StringLength = SQL_IS_INTEGER ) { return (SQLSetEnvAttr( mHenv, Attribute, ValuePtr, StringLength ) == SQL_SUCCESS) ? true : false; } bool ConnectionPoolingRelaxedMatch ( void ) { return (SQLSetEnvAttr( mHenv, SQL_ATTR_CP_MATCH, (SQLPOINTER)SQL_CP_RELAXED_MATCH, SQL_IS_INTEGER ) == SQL_SUCCESS) ? true : false; } // µ¥À̼­ ¼Ò½º¿¡ °ü¶õ Á¤º¸¸¦ ³Ñ°ÜÁØ´Ù. // SQL_FETCH_FIRST, SQL_FETCH_NEXT ... bool DataSources ( SQLUSMALLINT direction, SQLCHAR* dns, SQLSMALLINT cbDnsMax, SQLSMALLINT* cbDns, SQLCHAR* description, SQLSMALLINT cbDescriptionMax, SQLSMALLINT* cbDescription ) { SQLRETURN result = SQLDataSources( mHenv, direction, dns, cbDnsMax, cbDns, description, cbDescriptionMax, cbDescription ); if ( result == SQL_NO_DATA || result == SQL_ERROR ) return false; return true; } }; class cSQLConnection { friend class cSQLStatement; protected: // Á¢¼Ó ÇÚµé SQLHDBC mHdbc; public: cSQLConnection(void) : mHdbc( SQL_NULL_HDBC ) { } SQLHDBC GetSqlDbc ( void ) { return mHdbc; } // Á¢¼Ó ÇÚµéÀ» ÇÒ´çÇÑ´Ù. virtual bool AllocDbc ( cSQLEnvironment* sqlEnvironment ) { // SQLAllocHandle( SQL_HANDLE_DBC, sqlEnvironment->mHenv, &mHdbc ) return (SQLAllocConnect( sqlEnvironment->mHenv, &mHdbc ) == SQL_SUCCESS) ? true : false; } // Á¢¼Ó ÇÚµéÀ» ÇÒ´çÇÑ´Ù. virtual bool AllocDbc ( SQLHENV henv ) { // SQLAllocHandle( SQL_HANDLE_DBC, henv, &mHdbc ) return (SQLAllocConnect( henv, &mHdbc ) == SQL_SUCCESS) ? true : false; } // Á¢¼Ó ÇÚµéÀ» ÇØÁ¦ÇÑ´Ù. virtual void FreeDbc ( void ) { if ( mHdbc != SQL_NULL_HDBC ) { // SQLFreeHandle( SQL_HANDLE_DBC, mHdbc ) SQLFreeConnect( mHdbc ); mHdbc = SQL_NULL_HDBC; } } // °¡Àå ´Ü¼øÇÑ ¿¬°á ÇÔ¼ö virtual bool Connect ( SQLCHAR* dns, SQLCHAR* uid, SQLCHAR* pwd ) { SQLRETURN retcode; retcode = SQLConnect( mHdbc, dns, SQL_NTS, uid, SQL_NTS, pwd, SQL_NTS ); // if failed to connect, free the allocated mHdbc before return // ¸¸¾à ¿¬°áÀ» ½ÇÆÐÇÑ´Ù¸é, ¸®ÅÏÀü¿¡ mHdbc ÇÒ´çÀ» ÇØÁ¦ÇÑ´Ù. if ( retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO ) { //GetDiagRec( SQL_HANDLE_DBC, mHdbc ); Disconnect( ); return false; } /*-- retcode = SQLSetConnectAttr( mHdbc, SQL_ATTR_CONNECTION_TIMEOUT, (void*)5, 0 ); if ( retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO ) { //GetDiagRec( SQL_HANDLE_DBC, mHdbc ); Disconnect( ); return false; } */ // display any connection information if driver returns SQL_SUCCESS_WITH_INFO // if ( retcode == SQL_SUCCESS_WITH_INFO ) // GetDiagRec( SQL_HANDLE_DBC, mHdbc ); return true; } // Driver ¿¬°á ÇÔ¼ö virtual bool SQLConnect4XLS ( SQLCHAR* connStrIn, SQLSMALLINT connStrLen, SQLCHAR* connStrOut, SQLSMALLINT connStrOutMax, SQLSMALLINT* connStrOutLen ) { // DRIVER={Microsoft Excel Driver (*.xls)}; FIRSTROWHASNAMES=1; READONLY=0; CREATE_DB=\"test.xls\"; DBQ=test.xls; SQLRETURN retcode; retcode = SQLDriverConnect( mHdbc ,NULL ,connStrIn ,connStrLen ,connStrOut ,connStrOutMax ,connStrOutLen ,SQL_DRIVER_NOPROMPT ); // if failed to connect, free the allocated mHdbc before return // ¸¸¾à ¿¬°áÀ» ½ÇÆÐÇÑ´Ù¸é, ¸®ÅÏÀü¿¡ mHdbc ÇÒ´çÀ» ÇØÁ¦ÇÑ´Ù. if ( retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO ) { //GetDiagRec( SQL_HANDLE_DBC, mHdbc ); Disconnect( ); return false; } return true; } // SQL_AUTOCOMMIT_OFF = The driver uses manual-commit mode, // and the application must explicitly commit or roll back transactions with SQLEndTran. SQLRETURN AutocommitOff ( void ) { return SQLSetConnectAttr( mHdbc, SQL_ATTR_AUTOCOMMIT, (void*)SQL_AUTOCOMMIT_OFF, 0 ); } // SQL_AUTOCOMMIT_ON = The driver uses autocommit mode. // Each statement is committed immediately after it is executed. // This is the default. // Any open transactions on the connection are committed // when SQL_ATTR_AUTOCOMMIT is set to SQL_AUTOCOMMIT_ON to change from manual-commit mode to autocommit mode SQLRETURN AutocommitOn ( void ) { return SQLSetConnectAttr( mHdbc, SQL_ATTR_AUTOCOMMIT, (void*)SQL_AUTOCOMMIT_ON, 0 ); } // Completion Type SQL_COMMIT, SQL_ROLLBACK. SQLRETURN EndTran ( SQLSMALLINT completionType ) { return SQLEndTran( SQL_HANDLE_DBC, mHdbc, completionType ); } // SQL_COPT_SS_CONNECTION_DEAD reports the alive or dead state of a connection to a server. // The driver queries the Net-Library for the current state of the connection. // SQL_COPT_SS_CONNECTION_DEAD ´Â ¼­¹ö¿ÍÀÇ Á¢¼Ó»óŰ¡ À¯ÁöµÇ´ÂÁö ¶Ç´Â ²÷¾îÁ³´ÂÁö¸¦ ¾Ë·ÁÁØ´Ù. // µå¶óÀ̹ö´Â ÇöÀç Á¢¼Ó »óÅ Á¤º¸¸¦ "Net-Library"¿¡¼­ ¾ò´Â´Ù. virtual bool ConnectionDead ( void ) { SQLINTEGER ValuePtr; SQLINTEGER StringLengthPtr; // SQL_CD_TRUE: The connection to the server has been lost. // SQL_CD_FALSE: The connection is open and available for statement processing. // SQL_CD_TRUE: ¼­¹ö¿ÍÀÇ Á¢¼ÓÀÌ »ó½ÇµÇ¾ú´Ù. // SQL_CD_FALSE: Á¢¼ÓÀÌ ¿­·Á ÀÖÀ¸¸ç, ¸í·É¹® 󸮰¡ °¡´ÉÇÏ´Ù. SQLGetConnectAttr( mHdbc, SQL_COPT_SS_CONNECTION_DEAD, &ValuePtr, SQL_IS_INTEGER, &StringLengthPtr ); return (ValuePtr == SQL_CD_TRUE) ? true : false; } // ¿¬°áÀ» Á¾·áÇÑ´Ù. virtual void Disconnect ( void ) { if ( mHdbc != SQL_NULL_HDBC ) { SQLDisconnect( mHdbc ); } } public: virtual ~cSQLConnection(void) { Disconnect( ); FreeDbc( ); } }; class cSQLStatement { protected: // ¸í·É¹® ÇÚµé SQLHSTMT mHstmt; public: cSQLStatement(void) : mHstmt( SQL_NULL_HSTMT ) { } SQLHSTMT GetSqlStmt ( void ) { return mHstmt; } // ¸í·É¹® ÇÚµéÀ» ÇÒ´çÇÑ´Ù. virtual bool AllocStmt ( cSQLConnection* sqlConnection ) { // SQLAllocHandle( SQL_HANDLE_STMT, sqlConnection->mHdbc, &mHstmt ) return (SQLAllocStmt( sqlConnection->mHdbc, &mHstmt ) == SQL_SUCCESS) ? true : false; } // ¸í·É¹® ÇÚµéÀ» ÇÒ´çÇÑ´Ù. virtual bool AllocStmt ( SQLHDBC hdbc ) { // SQLAllocHandle( SQL_HANDLE_STMT, hdbc, &mHstmt ) return (SQLAllocStmt( hdbc, &mHstmt ) == SQL_SUCCESS) ? true : false; } // ¸í·É¹® ÇÚµéÀ» ÇØÁ¦ÇÑ´Ù. virtual void FreeStmt ( void ) { if ( mHstmt != SQL_NULL_HSTMT ) { // SQLFreeHandle( SQL_HANDLE_STMT, mHstmt ) SQLFreeStmt( mHstmt, SQL_DROP ); mHstmt = SQL_NULL_HSTMT; } } virtual bool Sequence ( void ) { SQLCHAR sqlstate[ SQL_SQLSTATE_SIZE + 1 ]; SQLINTEGER nativeErrorPtr; SQLCHAR messageText[ SQL_MAX_MESSAGE_LENGTH ]; SQLSMALLINT bufferLength = SQL_MAX_MESSAGE_LENGTH; SQLSMALLINT textLength = 0; SQLGetDiagRec( SQL_HANDLE_STMT, mHstmt, 1, sqlstate, &nativeErrorPtr, messageText, bufferLength, &textLength ); return (strcmp( (char*)sqlstate, "HY010" ) == 0) ? true : false; } virtual SQLRETURN Test ( char* message ) { SQLCHAR* statement = (SQLCHAR*)"SELECT ?"; SQLINTEGER strLenOrInd; SQLRETURN retcode; long messageLen = (long)strlen( message ); long cbMessage = SQL_NTS; SQLCHAR buffer[MAX_PATH]; long bufferLen = sizeof(buffer); retcode = SQLBindParameter( mHstmt, 0x1, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_VARCHAR, messageLen, 0, message, 0, &cbMessage ); retcode = SQLExecDirect( mHstmt, statement, SQL_NTS ); if ( retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO ) { // °á°ú È®ÀÎ. if ( SQLFetch( mHstmt ) == SQL_SUCCESS ) { SQLGetData( mHstmt, 0x01, SQL_C_CHAR, buffer, bufferLen, &(strLenOrInd=0) ); } // ÀúÀåÇÁ·Î½ÃÀú Äõ¸® ¸¶¹«¸®. while ( SQLMoreResults( mHstmt ) == SQL_SUCCESS ); // ¿­·ÁÀÖ´Â °á°ú ´Ý±â. (Close the open result set.) SQLCloseCursor( mHstmt ); } return retcode; } public: virtual ~cSQLStatement(void) { FreeStmt( ); } }; #endif // __ODBC_SQL_H__