void CCurRecordset::GetFieldValue(short nIndex, CString& strValue) { ASSERT_VALID(this); ASSERT(IsOpen()); // No data or no column info fetched yet if (GetODBCFieldCount() <= 0) { ASSERT(FALSE); return; } // Convert index to 1-based and check range nIndex++; if (nIndex < 1 || nIndex > GetODBCFieldCount()) { ThrowDBException(AFX_SQL_ERROR_FIELD_NOT_FOUND); } int nLen = GetTextLen(m_rgODBCFieldInfos[nIndex - 1].m_nSQLType, m_rgODBCFieldInfos[nIndex - 1].m_nPrecision); #ifndef _UNICODE CString& strData = strValue; #else CString strProxy; CString& strData = strProxy; #endif void* pvData = strData.GetBufferSetLength(nLen); // Now can actually get the data long nActualSize = GetData(m_pDatabase, m_hstmt, nIndex, SQL_C_CHAR, pvData, nLen, m_rgODBCFieldInfos[nIndex - 1].m_nSQLType); // Handle NULL data separately if (nActualSize == SQL_NULL_DATA) { // Clear value strValue.Empty(); } else { // May need to cleanup and call SQLGetData again if necessary GetLongCharDataAndCleanup(m_pDatabase, m_hstmt, nIndex, nActualSize, &pvData, nLen, strData, m_rgODBCFieldInfos[nIndex - 1].m_nSQLType); #ifdef _UNICODE // Now must convert string to UNICODE strValue = (LPCSTR)strData.GetBuffer(0); #endif // _UNIOCDE } if(m_rgODBCFieldInfos[nIndex - 1].m_nSQLType == SQL_BINARY || m_rgODBCFieldInfos[nIndex - 1].m_nSQLType == SQL_LONGVARBINARY || m_rgODBCFieldInfos[nIndex - 1].m_nSQLType == SQL_VARBINARY) if(!strValue.IsEmpty()) strValue = _T("0x") + strValue; }
CString CODBCRecordset::GetFieldName( int nField ) { // The field ID is invalid ASSERT( nField >= 0 ); ASSERT( nField < GetODBCFieldCount() ); CString cName; void* idx; POSITION pos = m_mapNameIdx.GetStartPosition(); while( pos != NULL ) { m_mapNameIdx.GetNextAssoc( pos, cName, idx ); if( (int)idx == nField ) return cName; } cName.Empty(); return cName; }
// Called by Move() to load info about all the fields void CODBCRecordset::LoadFieldNamesMap() { m_mapNameIdx.RemoveAll(); int nFields = m_nFields = GetODBCFieldCount(); // Smart storage reallocation for the fields buffer if( m_AllocatedFields < nFields ) { Clear(); m_fields = new CDBField[ m_nFields ]; m_AllocatedFields = m_nFields; } // Load field names map CODBCFieldInfo fi; CString cName; for( int i = 0; i < nFields; i++ ) { // Clear the previously allocated storage object m_fields[i].Clear(); // Determine the field type and initialize the data buffer GetODBCFieldInfo( i, fi ); AllocDataBuffer( m_fields[i], fi ); // Set the field name fi.m_strName.MakeUpper(); cName = fi.m_strName; // Make different field names for the fields with // equal names. int fldCount = 1; while( GetFieldID( cName ) != -1 ) { fldCount++; cName.Format( "%s%d", fi.m_strName, fldCount ); } m_fields[i].m_cName = cName; m_mapNameIdx.SetAt( cName, (void*)i ); } }
void CCurRecordset::PreBindFields() { WBOUT << "Binding Field columns..." << endl; const auto nCount = GetODBCFieldCount(); WBOUT << "Total ODBCFieldCount :" << nCount << endl; for (auto nCol = 0; nCol < nCount; nCol++) { CODBCFieldInfo info; GetODBCFieldInfo(nCol, info); WBOUT << "Fieldname = " << static_cast<LPCTSTR>(info.m_strName) << endl; m_listNames.AddTail(info.m_strName); m_listValues.AddTail(CString("n",255)); } m_nFields = nCount; // CRecordset::AllocStatusArrays(); WBOUT << "Fields bounded successfully..." << endl; }
void CCurRecordset::AllocAndCacheFieldInfo() { m_nResultCols = -1; ASSERT(GetODBCFieldCount() < 0); if (m_rgODBCFieldInfos != NULL) { delete[] m_rgODBCFieldInfos; m_rgODBCFieldInfos = NULL; } RETCODE nRetCode; SWORD nActualLen; // Cache the number of result columns. AFX_ODBC_CALL(::SQLNumResultCols(m_hstmt, &m_nResultCols)); if (!Check(nRetCode)) { TRACE(_T("Error: Can't get field info.\n")); AfxThrowDBException(nRetCode, m_pDatabase, m_hstmt); } // If there are no fields, quit now if (m_nResultCols == 0) return; // Allocate buffer and get the ODBC meta data. m_rgODBCFieldInfos = new CODBCFieldInfo[m_nResultCols]; LPSTR lpszFieldName; #ifdef _UNICODE // Need proxy to temporarily store non-UNICODE name. lpszFieldName = new char[MAX_FNAME_LEN + 1]; #endif // Get the field info for each field. for (WORD n = 1; n <= GetODBCFieldCount(); n++) { #ifndef _UNICODE // Reset the buffer to point to next element. lpszFieldName = m_rgODBCFieldInfos[n - 1].m_strName.GetBuffer(MAX_FNAME_LEN + 1); #endif AFX_ODBC_CALL(::SQLDescribeCol(m_hstmt, n, (UCHAR*)lpszFieldName, MAX_FNAME_LEN, &nActualLen, &m_rgODBCFieldInfos[n - 1].m_nSQLType, &m_rgODBCFieldInfos[n - 1].m_nPrecision, &m_rgODBCFieldInfos[n - 1].m_nScale, &m_rgODBCFieldInfos[n - 1].m_nNullability)); #ifndef _UNICODE m_rgODBCFieldInfos[n - 1].m_strName.ReleaseBuffer(nActualLen); #else // Copy the proxy data to correct element. m_rgODBCFieldInfos[n - 1].m_strName = lpszFieldName; #endif if (!Check(nRetCode)) { TRACE1("Error: ODBC failure getting field #%d info.\n", n); AfxThrowDBException(nRetCode, m_pDatabase, m_hstmt); } } #ifdef _UNICODE delete[] lpszFieldName; #endif }