#include "StdAfx.h" #include "OtlConnHost.h" #include "OtlDB.h" #include IMPLEMENT_DYNAMIC( COtlConnHost, CWnd ) COtlConnHost::COtlConnHost( void ) { CreateEx( 0, AfxRegisterWndClass( CS_GLOBALCLASS ), "", 0, 0, 0, 0, 0, 0, 0 ); ZeroMemory( m_szConnStr, OTL_MAX_BUFF_SIZE ); ZeroMemory( m_szLastError, OTL_MAX_BUFF_SIZE ); SetConnStatus( OTL_CONN_DISCONNECTED ); // 初始化SQL缓冲区 m_pListSQL = new CList; // m_DbType = DB_SQLServer;//初始化数据类型为SQLServer // 初始化为多线程环境 otl_connect::otl_initialize( 1 ); } COtlConnHost::~COtlConnHost( void )throw() { DestroyWindow(); } BEGIN_MESSAGE_MAP( COtlConnHost, CWnd ) ON_MESSAGE( WM_OTL_CONN_ESTABLISHED, OnConnEstablished ) END_MESSAGE_MAP() /***************************************************************** **【函数名称】 ProcConnDetected **【函数功能】 数据库连接检测线程函数 **【参数】 pParam COtlConnHost类指针 **【返回值】 *****************************************************************/ UINT ProcConnDetected( LPVOID pParam ) { COtlConnHost* pHost = ( COtlConnHost* )pParam; pHost->Disconnect(); pHost->SetConnStatus( OTL_CONN_CONNECTING ); // 连接信息 CString strConnString = pHost->GetConnString(); // 开始自动重连 while( TRUE ) { CHAR szErrMsg[OTL_MAX_BUFF_SIZE] = { 0 }; if( pHost->TestConnect( strConnString, szErrMsg ) ) // 连接可用 { break; } // end if } // end while // 发送连接可用事件 pHost->PostMessage( WM_OTL_CONN_ESTABLISHED, 0, 0 ); return 0; } /***************************************************************** **【函数名称】 Connect **【函数功能】 连接数据库(连接注册表中默配置数据库) **【参数】 **【返回值】 *****************************************************************/ BOOL COtlConnHost::Connect() { BOOL bIsConnect = TRUE; // 获取可用的连接字符串 if( GetRegDbInfo( m_szConnStr ) ) { try { m_OtlConn.rlogon( m_szConnStr, 1 ); // 默认为自动commit SetConnStatus( OTL_CONN_CONNECTED ); DB_TYPE DbType = GetDSNInfo( m_DSN ); if( DB_Error == DbType ) { sprintf_s( m_szLastError, OTL_MAX_BUFF_SIZE, "数据源:%s查找失败,请确认数据源是否正常!", m_DSN.GetBuffer(0) ); m_DSN.ReleaseBuffer(); return FALSE; } m_DbType = DbType; return TRUE; } catch( otl_exception& e ) { sprintf_s( m_szLastError, OTL_MAX_BUFF_SIZE, "Code = %d, Error = %s", e.code, e.msg ); bIsConnect = FALSE; } } else { bIsConnect = FALSE; } if( !bIsConnect ) { MessageBox( _T( "连接数据库失败,请检测并确认数据源是否正常!" ), _T( "连接数据库失败" ), MB_ICONWARNING ); } return FALSE; } /***************************************************************** **【函数名称】 Connect **【函数功能】 连接数据库(连接连接字符串指定的数据库) **【参数】 **【返回值】 *****************************************************************/ BOOL COtlConnHost::Connect( LPCTSTR lpszConnString ) { try { m_OtlConn.rlogon( lpszConnString, 1 ); SetConnStatus( OTL_CONN_CONNECTED ); strcpy_s( m_szConnStr, OTL_MAX_BUFF_SIZE, lpszConnString ); } catch( otl_exception& e ) { sprintf_s( m_szLastError, OTL_MAX_BUFF_SIZE, "Code = %d, Error = %s", e.code, e.msg ); return FALSE; } return TRUE; } /***************************************************************** **【函数名称】 Disconnect **【函数功能】 断开数据库连接 **【参数】 **【返回值】 *****************************************************************/ void COtlConnHost::Disconnect() { CSingleLock lock( &m_LockSection, TRUE ); // 数据库连接断开成功,设置连接状态 m_nConnStatus = OTL_CONN_DISCONNECTED; m_OtlConn.logoff(); // 断开数据库连接 } /***************************************************************** **【函数名称】 InsertConstant **【函数功能】 恒量插入(单数据) **【参数】 lpszSQL Insert语句 **【返回值】 *****************************************************************/ BOOL COtlConnHost::InsertConstant( LPCTSTR lpszSQL ) { DB_TYPE type = GetDBType(); CString strSQL = lpszSQL; if( DB_MySQL == type ) strSQL = GetStringForMySQL( lpszSQL ); try { CSingleLock lock( &m_LockSection, TRUE ); otl_stream o( 1, strSQL, m_OtlConn ); } catch( otl_exception& e ) { if( m_pListSQL->GetCount() < 3000 ) m_pListSQL->AddTail( lpszSQL ); // 缓存3000条 this->ProcException( e ); return FALSE; } // end try return TRUE; } /***************************************************************** **【函数名称】 InsertConstantForMySQL **【函数功能】 恒量插入(单数据) 注:该函数在使用MYSQL数据库时,执行插入操作使用。 因为其传入字符串中的转义字符‘\’必须写成‘\\’,所以与InsertConstant区分开来使用 **【参数】 lpszSQL SQL执行语句 **【返回值】 *****************************************************************/ BOOL COtlConnHost::InsertConstantForMySQL( LPCTSTR lpszSQL ) { CString strQuery = lpszSQL; int len = strQuery.GetLength(); CString str = ""; char ch; for( int i = 0; i < len; i++ ) { ch = ( char )strQuery.GetAt( i ); if( ch == '\\' ) str += "\\\\"; else str += strQuery.GetAt( i ); } //otl_cursor::direct_exec(m_OtlConn, "SET NAMES 'GB2312'", otl_exception::enabled); return InsertConstant( str ); } /***************************************************************** **【函数名称】 ExecCommand **【函数功能】 直接命令执行 注:在执行删除表命令时,请使用函数ExecComForDropTable 否则会出现命令执行失败问题。 **【参数】 lpszSQL SQL执行语句 **【返回值】 *****************************************************************/ BOOL COtlConnHost::ExecCommand( LPCTSTR lpszSQL ) { DB_TYPE type = GetDBType(); CString strSQL = lpszSQL; CSingleLock lock(&m_LockSection); if (DB_MySQL == type) { strSQL = GetStringForMySQL(lpszSQL); } try { // 判断连接是否正常,不正常重新连接 if (!m_OtlConn.connected) { m_OtlConn.rlogon(m_szConnStr, 1); } //CSingleLock lock( &m_LockSection, TRUE ); lock.Lock(); long nResult = otl_cursor::direct_exec(m_OtlConn, strSQL, otl_exception::enabled); lock.Unlock(); return true; } catch( otl_exception& e ) { this->ProcException( e ); lock.Unlock(); return FALSE; } } /***************************************************************** **【函数名称】 ExecComForDropTable **【函数功能】 删除表命令执行 注释:函数direct_exec的第三个参数为enabled时,可获取异常信息, 但在删除表时该参数需设置为disabled,否则会出现命令执行失败。 [4/2/2013 zst] **【参数】 lpszSQL SQL执行语句 **【返回值】 *****************************************************************/ void COtlConnHost::ExecComForDropTable( LPCTSTR lpszSQL ) { CSingleLock lock( &m_LockSection, TRUE ); otl_cursor::direct_exec( m_OtlConn, lpszSQL, otl_exception::disabled ); } /***************************************************************** **【函数名称】 GetSingleDataString **【函数功能】 获取字符串单值 **【参数】 IN lpszSQL SQL查询语句 OUT lpValue 返回值 **【返回值】 *****************************************************************/ BOOL COtlConnHost::GetSingleDataString( LPCTSTR lpszSQL, CHAR* lpValue ) { // char szTmp[OTL_MAX_BUFF_SIZE] = { 0 }; // memset(lpValue, 0, nLen); try { CSingleLock lock( &m_LockSection, TRUE ); otl_stream o( 1, lpszSQL, m_OtlConn ); if( !o.eof() ) { o >> lpValue; // Unicode// [1/23/2013 zst] // WideCharToMultiByte(0, 0, szTmp, wcslen(szTmp), lpValue, nLen, 0, 0); return TRUE; } } catch( otl_exception& e ) { this->ProcException( e ); } return FALSE; } /***************************************************************** **【函数名称】 GetSingleDataText **【函数功能】 获取Text串单值 **【参数】 IN lpszSQL SQL查询语句 OUT lpValue 返回值 **【返回值】 *****************************************************************/ BOOL COtlConnHost::GetSingleDataText( LPCTSTR lpszSQL, CHAR* lpValue ) { otl_long_string strOut; // SQLWCHAR szTmp[OTL_MAX_TEXT_SIZE] = { 0 }; try { CSingleLock lock( &m_LockSection, TRUE ); otl_stream o( 1, lpszSQL, m_OtlConn ); if( !o.eof() ) { o >> strOut; for( int i = 0; i < strOut.len() && i < OTL_MAX_TEXT_SIZE; i++ ) { lpValue[i] = strOut[i]; // WideCharToMultiByte(0, 0, szTmp, wcslen(szTmp), lpValue, nLen, 0, 0); } } return TRUE; } catch( otl_exception& e ) { this->ProcException( e ); } return FALSE; } /***************************************************************** **【函数名称】 GetSingleDataInt **【函数功能】 获取整型单值 **【参数】 IN lpszSQL SQL查询语句 OUT nValue 返回值 **【返回值】 *****************************************************************/ BOOL COtlConnHost::GetSingleDataInt( LPCTSTR lpszSQL, LONG& nValue ) { try { CSingleLock lock( &m_LockSection, TRUE ); otl_stream o( 1, lpszSQL, m_OtlConn ); if( !o.eof() ) { o >> nValue; return TRUE; } } catch( otl_exception& e ) { this->ProcException( e ); } return FALSE; } /***************************************************************** **【函数名称】 InitOtlStream **【函数功能】 初始化记录集数据流 **【参数】 lpszSQL SQL查询语句 **【返回值】 *****************************************************************/ BOOL COtlConnHost::InitOtlStream( LPCTSTR lpszSQL, otl_stream** pOtlStream, OtlIterator *pIterator ) { try { CSingleLock lock( &m_LockSection, TRUE ); otl_stream* pStream = new otl_stream( 200, lpszSQL, m_OtlConn ); pIterator->attach( *pStream ); *pOtlStream = pStream; return TRUE; } catch( otl_exception& e ) { this->ProcException( e ); } return FALSE; } /***************************************************************** **【函数名称】 InitOtlStream **【函数功能】 是否已遍历到记录保结尾 **【参数】 lpszSQL SQL查询语句 **【返回值】 *****************************************************************/ BOOL COtlConnHost::IsEOF( otl_stream* pOtlStream ) { CSingleLock lock( &m_LockSection, TRUE ); return pOtlStream->eof() ? TRUE : FALSE; } /***************************************************************** **【函数名称】 GetNextDataInt **【函数功能】 获取当前记录的下一个数据(INT) **【参数】 nValue 要获取的数据内容 **【返回值】 *****************************************************************/ BOOL COtlConnHost::GetNextDataInt( otl_stream* pOtlStream, LONG& nValue ) { try { CSingleLock lock( &m_LockSection, TRUE ); *pOtlStream >> nValue; } catch( otl_exception& e ) { this->ProcException( e ); return FALSE; } return TRUE; } /***************************************************************** **【函数名称】 GetNextDataString **【函数功能】 获取当前记录的下一个数据(String) **【参数】 lpValue 要获取的数据内容 nLen 字符串缓冲区长度 **【返回值】 *****************************************************************/ BOOL COtlConnHost::GetNextDataString( otl_stream* pOtlStream, CHAR* lpValue, UINT nLen ) { SQLWCHAR szTmp[OTL_MAX_BUFF_SIZE] = { 0 }; memset( lpValue, 0, nLen ); try { CSingleLock lock( &m_LockSection, TRUE ); WideCharToMultiByte( 0, 0, szTmp, wcslen( szTmp ), lpValue, nLen, 0, 0 ); } catch( otl_exception& e ) { this->ProcException( e ); return FALSE; } return TRUE; } /***************************************************************** **【函数名称】 __DetectConn **【函数功能】 启动连接检测 **【参数】 **【返回值】 *****************************************************************/ void COtlConnHost::__DetectConn() { switch( m_nConnStatus ) { case OTL_CONN_CONNECTED: // 已连接 { AfxBeginThread( ProcConnDetected, ( LPVOID )this ); } break; case OTL_CONN_DISCONNECTED: // 未连接 case OTL_CONN_CONNECTING: // 正在连接 { // 不处理 } break; } // end switch } /***************************************************************** **【函数名称】 GetRegDbInfo **【函数功能】 从注册表读取数据库信息 **【参数】 **【返回值】 *****************************************************************/ BOOL COtlConnHost::GetRegDbInfo( LPSTR lpConnStr ) { CRegKey key; CString strDsn, strUer, strPass; // 打开键值失败 if( key.Open( HKEY_CURRENT_USER, "Software\\FirstStep\\Database", KEY_READ ) != ERROR_SUCCESS ) { key.Create( HKEY_CURRENT_USER, "Software\\FirstStep\\Database" ); return FALSE; } // end if // DSN名称 ULONG nSize = OTL_REG_KEY_SIZE; CHAR szTmp[OTL_REG_KEY_SIZE] = { 0 }; key.QueryStringValue( "DSN", szTmp, &nSize ); strDsn = szTmp; m_DSN = strDsn;//保存数据源名称,作为判断数据源类型使用 // 用户名 nSize = OTL_REG_KEY_SIZE; memset( szTmp, 0, OTL_REG_KEY_SIZE ); key.QueryStringValue( "USER", szTmp, &nSize ); strUer = szTmp; // 口令 nSize = OTL_REG_KEY_SIZE; memset( szTmp, 0, OTL_REG_KEY_SIZE ); key.QueryStringValue( "PASS", szTmp, &nSize ); strPass = szTmp; // 生成连接字符串 sprintf_s( lpConnStr, OTL_MAX_BUFF_SIZE, "DSN=%s; UID=%s; PWD=%s;", strDsn.GetBuffer(0), strUer.GetBuffer(0), strPass.GetBuffer(0)); strDsn.ReleaseBuffer(); strUer.ReleaseBuffer(); strPass.ReleaseBuffer(); return TRUE; } /***************************************************************** **【函数名称】 GetDSNInfo **【函数功能】 从注册表获取数据源所属数据库 **【参数】 LPstrDSN 数据源名称 **【返回值】 数据库类型 *****************************************************************/ DB_TYPE COtlConnHost::GetDSNInfo( LPCTSTR LPstrDSN ) { CRegKey key; CString strPath; strPath.Format( _T( "Software\\ODBC\\ODBC.INI\\%s" ), LPstrDSN ); if( key.Open( HKEY_LOCAL_MACHINE, strPath, KEY_READ ) == ERROR_SUCCESS ) { // DSN名称 ULONG nSize = OTL_REG_KEY_SIZE; CHAR szTmp[OTL_REG_KEY_SIZE] = { 0 }; key.QueryStringValue( "Driver", szTmp, &nSize ); CString strDriver = szTmp; std::cout << szTmp << std::endl; if( ( -1 != strDriver.MakeUpper().Find( _T( "SQLSRV" ) ) ) || ( -1 != strDriver.MakeUpper().Find( _T( "SQLNCLI" ) ) ) ) { return DB_SQLServer; } else if( -1 != strDriver.MakeLower().Find( _T( "myodbc" ) ) ) { return DB_MySQL; } else if ((-1 != strDriver.MakeLower().Find(_T("sqora32")))|| (-1 != strDriver.MakeLower().Find(_T("sqoras32")))) { return DB_Oracle; } else { return DB_Error; } } return DB_Error; } /***************************************************************** **【函数名称】 TestConnect **【函数功能】 测试连接 **【参数】 lpszConnString 要测试的连接字符串 lpErrInfo 如果测试失败,返回错误信息 **【返回值】 *****************************************************************/ BOOL COtlConnHost::TestConnect( LPCTSTR lpszConnString, LPSTR lpErrInfo ) { try { otl_connect conn; conn.rlogon( lpszConnString, 0 ); // 连接测试 conn.logoff(); } catch( otl_exception& e ) { sprintf_s( lpErrInfo, OTL_MAX_BUFF_SIZE, "Code = %d, Error = %s", e.code, e.msg ); return FALSE; } return TRUE; } /***************************************************************** **【函数名称】 OnConnEstablished **【函数功能】 连接可用事件响应 **【参数】 **【返回值】 *****************************************************************/ LRESULT COtlConnHost::OnConnEstablished( WPARAM wParam, LPARAM lParam ) { try { CSingleLock lock( &m_LockSection, TRUE ); m_OtlConn.rlogon( m_szConnStr, 1 ); // 重新连接 // 将缓冲区插入数据入库 while( !m_pListSQL->IsEmpty() ) { try { otl_stream o( 1, m_pListSQL->GetHead(), m_OtlConn ); } catch( ... ) { } m_pListSQL->RemoveHead(); } } catch( otl_exception& e ) { sprintf_s( m_szLastError, OTL_MAX_BUFF_SIZE, "Code = %d, Error = %s", e.code, e.msg ); return S_FALSE; } SetConnStatus( OTL_CONN_CONNECTED ); return S_OK; } /***************************************************************** **【函数名称】 ProcException **【函数功能】 数据库操作异常处理 **【参数】 **【返回值】 *****************************************************************/ void COtlConnHost::ProcException( otl_exception& e ) { // 获取错误信息 sprintf_s( m_szLastError, OTL_MAX_BUFF_SIZE, "Code = %d, Error = %s", e.code, e.msg ); // 断开数据库连接,并重连 __DetectConn(); } /***************************************************************** **【函数名称】 MoveNextRow **【函数功能】 把指定迭代器移动到下一行 **【参数】 迭代器指针 **【返回值】 成功返回TURE 失败返回FALSE *****************************************************************/ BOOL COtlConnHost::MoveNextRow( OtlIterator * pIterator ) { BOOL bResult = FALSE; try { bResult = pIterator->next_row(); } catch( otl_exception& e ) { sprintf_s( m_szLastError, OTL_MAX_BUFF_SIZE, "Code = %d, Error = %s", e.code, e.msg ); return FALSE; } return bResult; } /***************************************************************** **【函数名称】 GetValueInt **【函数功能】 指定迭代器的当前行 获取指定字段的数据 **【参数】 OtlIterator * pIterator 迭代器指针 char *pColName 字段名 int &nValue 返回整形字段值 **【返回值】 成功返回TURE 失败返回FALSE *****************************************************************/ BOOL COtlConnHost::GetValueInt( OtlIterator * pIterator, char *pColName, int &nValue ) { try { pIterator->get( pColName, nValue ); } catch( otl_exception& e ) { sprintf_s( m_szLastError, OTL_MAX_BUFF_SIZE, "Code = %d, Error = %s", e.code, e.msg ); return FALSE; } return TRUE; } /***************************************************************** **【函数名称】 GetValueString **【函数功能】 指定迭代器的当前行 获取指定字段的数据 **【参数】 OtlIterator * pIterator 迭代器指针 char *pColName 字段名 pValue 返回字符型数据 **【返回值】 成功返回TURE 失败返回FALSE *****************************************************************/ BOOL COtlConnHost::GetValueString( OtlIterator * pIterator, char *pColName, char *pValue ) { try { pIterator->get( pColName, pValue ); } catch( otl_exception& e ) { sprintf_s( m_szLastError, OTL_MAX_BUFF_SIZE, "Code = %d, Error = %s", e.code, e.msg ); return FALSE; } return TRUE; } /***************************************************************** **【函数名称】 GetValueText **【函数功能】 指定迭代器的当前行 获取指定字段的数据 **【参数】 OtlIterator * pIterator 迭代器指针 char *pColName 字段名 pValue 返回字符型数据 **【返回值】 成功返回TURE 失败返回FALSE *****************************************************************/ BOOL COtlConnHost::GetValueText( OtlIterator * pIterator, char *pColName, char *pValue ) //获取指定字段值 较大文本值 { try { pIterator->get( pColName, pValue ); } catch( otl_exception& e ) { sprintf_s( m_szLastError, OTL_MAX_BUFF_SIZE, "Code = %d, Error = %s", e.code, e.msg ); return FALSE; } return TRUE; } /***************************************************************** **【函数名称】 GetValueFloat **【函数功能】 指定迭代器的当前行 获取指定字段的数据 **【参数】 OtlIterator * pIterator 迭代器指针 char *pColName 字段名 Value 返回浮点型数据 **【返回值】 成功返回TURE 失败返回FALSE *****************************************************************/ BOOL COtlConnHost::GetValueFloat( OtlIterator * pIterator, char *pColName, float& Value ) { try { pIterator->get( pColName, Value ); } catch( otl_exception& e ) { sprintf_s( m_szLastError, OTL_MAX_BUFF_SIZE, "Code = %d, Error = %s", e.code, e.msg ); return FALSE; } return TRUE; } /***************************************************************** **【函数名称】 GetValueIntByIndex **【函数功能】 指定迭代器的当前行 获取指定字段的数据 **【参数】 OtlIterator * pIterator 迭代器指针 const int pos 列索引 int &nValue 返回整形字段值 **【返回值】 成功返回TURE 失败返回FALSE *****************************************************************/ BOOL COtlConnHost::GetValueIntByIndex( OtlIterator * pIterator, const int pos, int &nValue ) { try { pIterator->get( pos, nValue ); } catch( otl_exception& e ) { sprintf_s( m_szLastError, OTL_MAX_BUFF_SIZE, "Code = %d, Error = %s", e.code, e.msg ); return FALSE; } return TRUE; } /***************************************************************** **【函数名称】 GetValueStrByIndex **【函数功能】 指定迭代器的当前行 获取指定字段的数据 **【参数】 OtlIterator * pIterator 迭代器指针 const int pos 列索引 pValue 返回字符型数据 **【返回值】 成功返回TURE 失败返回FALSE *****************************************************************/ BOOL COtlConnHost::GetValueStrByIndex( OtlIterator * pIterator, const int pos, char *pValue ) { try { pIterator->get( pos, pValue ); } catch( otl_exception& e ) { sprintf_s( m_szLastError, OTL_MAX_BUFF_SIZE, "Code = %d, Error = %s", e.code, e.msg ); return FALSE; } return TRUE; } /***************************************************************** **【函数名称】 GetValueTextByIndex **【函数功能】 指定迭代器的当前行 获取指定字段的数据 **【参数】 OtlIterator * pIterator 迭代器指针 const int pos 字段索引 pValue 返回字符型数据 **【返回值】 成功返回TURE 失败返回FALSE *****************************************************************/ BOOL COtlConnHost::GetValueTextByIndex( OtlIterator * pIterator, const int pos, char *pValue ) { try { pIterator->get( pos, pValue ); } catch( otl_exception& e ) { sprintf_s( m_szLastError, OTL_MAX_BUFF_SIZE, "Code = %d, Error = %s", e.code, e.msg ); return FALSE; } return TRUE; } /***************************************************************** **【函数名称】 GetValueFloatByIndex **【函数功能】 指定迭代器的当前行 获取指定字段的数据 **【参数】 OtlIterator * pIterator 迭代器指针 const int pos 字段索引 Value 返回浮点型数据 **【返回值】 成功返回TURE 失败返回FALSE *****************************************************************/ BOOL COtlConnHost::GetValueFloatByIndex( OtlIterator * pIterator, const int pos, float& Value ) { try { pIterator->get( pos, Value ); } catch( otl_exception& e ) { sprintf_s( m_szLastError, OTL_MAX_BUFF_SIZE, "Code = %d, Error = %s", e.code, e.msg ); return FALSE; } return TRUE; } /***************************************************************** **【函数名称】 GetStringForMySQL **【函数功能】 转换字符串为MYsql数据库可以正常使用字符串,主要针对符号‘/’ **【参数】 LPCTSTR LPstr 被转字符串指针 **【返回值】 返回被转后的字符串 *****************************************************************/ CString COtlConnHost::GetStringForMySQL( LPCTSTR LPstr ) { CString strQuery = LPstr; int len = strQuery.GetLength(); CString str = ""; char ch; for( int i = 0; i < len; i++ ) { ch = ( char )strQuery.GetAt( i ); if( ch == '\\' ) str += "\\\\"; else str += strQuery.GetAt( i ); } return str; } /***************************************************************** **【函数名称】 CallStoredProc **【函数功能】 调用存储过程 **【参数】 a_DeclareWord:存储过程声明语句 **【返回值】 *****************************************************************/ COtlStoredProc* COtlConnHost::CallStoredProc( const CString& a_DeclareWord ) { COtlStoredProc* pProc = NULL; try { CSingleLock lock( &m_LockSection, TRUE ); pProc = new COtlStoredProc( this, a_DeclareWord ); } catch( otl_exception& e ) { sprintf_s( m_szLastError, OTL_MAX_BUFF_SIZE, "Code = %d, Error = %s", e.code, e.msg ); } return pProc; } /***************************************************************** **【函数名称】 Input **【函数功能】 调用存储过程输入参数 **【参数】 a_Stream:OTL流 a_StrParam:输入字符型参数 **【返回值】 *****************************************************************/ BOOL COtlConnHost::Input( otl_stream& a_Stream, LPCTSTR a_StrParam ) { try { CSingleLock lock( &m_LockSection, TRUE ); a_Stream << a_StrParam; } catch( otl_exception& e ) { sprintf_s( m_szLastError, OTL_MAX_BUFF_SIZE, "Code = %d, Error = %s", e.code, e.msg ); return FALSE; } return TRUE; } /***************************************************************** **【函数名称】 CallStoredProc **【函数功能】 调用存储过程输入参数 **【参数】 a_Stream:OTL流 a_UintParam:输入UINT型参数 **【返回值】 *****************************************************************/ BOOL COtlConnHost::Input( otl_stream& a_Stream, UINT a_UintParam ) { try { CSingleLock lock( &m_LockSection, TRUE ); a_Stream << a_UintParam; } catch( otl_exception& e ) { sprintf_s( m_szLastError, OTL_MAX_BUFF_SIZE, "Code = %d, Error = %s", e.code, e.msg ); return FALSE; } return TRUE; } /***************************************************************** **【函数名称】 CallStoredProc **【函数功能】 调用存储过程输入参数 **【参数】 a_Stream:OTL流 a_IntParam:输入INT型参数 **【返回值】 *****************************************************************/ BOOL COtlConnHost::Input( otl_stream& a_Stream, int a_IntParam ) { try { CSingleLock lock( &m_LockSection, TRUE ); a_Stream << a_IntParam; } catch( otl_exception& e ) { sprintf_s( m_szLastError, OTL_MAX_BUFF_SIZE, "Code = %d, Error = %s", e.code, e.msg ); return FALSE; } return TRUE; } /***************************************************************** **【函数名称】 CallStoredProc **【函数功能】 调用存储过程返回值 **【参数】 a_Stream:OTL流 a_UintReturn:返回值 **【返回值】 *****************************************************************/ BOOL COtlConnHost::Output( otl_stream& a_Stream, UINT& a_UintReturn ) { try { CSingleLock lock( &m_LockSection, TRUE ); a_Stream >> a_UintReturn; } catch( otl_exception& e ) { sprintf_s( m_szLastError, OTL_MAX_BUFF_SIZE, "Code = %d, Error = %s", e.code, e.msg ); return FALSE; } return TRUE; } /***************************************************************** **【函数名称】 CallStoredProc **【函数功能】 调用存储过程返回值 **【参数】 a_Stream:OTL流 a_IntParam:返回值 **【返回值】 *****************************************************************/ BOOL COtlConnHost::Output( otl_stream& a_Stream, int& a_IntParam ) { try { CSingleLock lock( &m_LockSection, TRUE ); a_Stream >> a_IntParam; } catch( otl_exception& e ) { sprintf_s( m_szLastError, OTL_MAX_BUFF_SIZE, "Code = %d, Error = %s", e.code, e.msg ); return FALSE; } return TRUE; } /***************************************************************** **【函数名称】 CallStoredProc **【函数功能】 调用存储过程返回值 **【参数】 a_Stream:OTL流 a_StrParam:返回值 **【返回值】 *****************************************************************/ BOOL COtlConnHost::Output( otl_stream& a_Stream, LPTSTR a_StrParam ) { try { CSingleLock lock( &m_LockSection, TRUE ); a_Stream >> a_StrParam; } catch( otl_exception& e ) { sprintf_s( m_szLastError, OTL_MAX_BUFF_SIZE, "Code = %d, Error = %s", e.code, e.msg ); return FALSE; } return TRUE; } /***************************************************************** **【函数名称】 CallStoredProc **【函数功能】 调用存储过程返回值 **【参数】 a_Stream:OTL流 a_floatParam:返回值 **【返回值】 *****************************************************************/ BOOL COtlConnHost::Output( otl_stream& a_Stream, float a_floatParam ) { try { CSingleLock lock( &m_LockSection, TRUE ); a_Stream >> a_floatParam; } catch( otl_exception& e ) { sprintf_s( m_szLastError, OTL_MAX_BUFF_SIZE, "Code = %d, Error = %s", e.code, e.msg ); return FALSE; } return TRUE; }