DBSTATUS dbStatus; DBTYPE dbType; CString str; double dValue; long lValue; // pAccessor 是一个指向CDynamicAccessor对象的指针 // nCol是读取的列下标 pAccessor->GetStatus(nCol, &dbStatus); if(dbStatus != DBSTATUS_S_ISNULL && pAccessor->GetColumnType(nCol, &dbType)) { switch (dbType) { case DBTYPE_VARIANT: vt = COleVariant((LPCVARIANT)pAccessor->GetValue(nCol)); break; case DBTYPE_STR: str = (LPCSTR)pAccessor->GetValue(nCol); break; case DBTYPE_WSTR: case DBTYPE_BSTR: str = (LPCWSTR)pAccessor->GetValue(nCol); break; case DBTYPE_I1: case DBTYPE_UI1: lValue = (long)(*((BYTE*)pAccessor->GetValue(nCol))); break; case DBTYPE_I2: case DBTYPE_UI2: lValue = (long)(*((short*)pAccessor->GetValue(nCol))); break; case DBTYPE_I4: case DBTYPE_UI4: lValue = (long)(*((long*)pAccessor->GetValue(nCol))); break; case DBTYPE_R4: dValue = (double)(*((float*)pAccessor->GetValue(nCol))); break; case DBTYPE_R8: dValue = *((double*)pAccessor->GetValue(nCol)); break; case DBTYPE_NUMERIC: { DB_NUMERIC num; if(pAccessor->GetValue(nCol, &num)) { dValue = (double)*((__int64*)num.val); while(num.scale-- > 0) dValue /= 10; if(num.sign == 0) dValue = -dValue; } } break; case DBTYPE_VARNUMERIC: { // MSDN中有这部分的代码,不过有错误,这儿做了修正 dValue = 0; unsigned long nColumn = nCol; DB_VARNUMERIC* pnum; pAccessor->TranslateColumnNo(nColumn); pnum = (DB_VARNUMERIC*)pAccessor->_GetDataPtr(nColumn); ULONG uLength = 0; pAccessor->GetLength(nCol, &uLength); int prec = ( int )pnum->precision; int scale = ( int )pnum->scale; int sign = ( int ) ( pnum->sign > 0 ) ? 1 : -1; BYTE hi, lo; double multiplier = 1; double adjust = 1; uLength -= (sizeof(DBTYPE_VARNUMERIC) - 1); for( ULONG i = 0, j = 0 ; i < uLength ; i++, j+=2 ) { hi = lo = pnum->val[ i ]; lo <<= 4; lo >>= 4; dValue += ( ( ( ULONG ) lo ) * multiplier ); multiplier *= 16; hi >>= 4; dValue += ( ( ( ULONG ) hi ) * multiplier ); multiplier *= 16; } adjust *= pow(10, scale) * sign; dValue /= adjust; } break; case DBTYPE_DBDATE: { DBDATE dbDate; if (pAccessor->GetValue(nCol, &dbDate)) { CTime tm(dbDate.year, dbDate.month, dbDate.day, 0, 0, 0); } } break; case DBTYPE_DBTIMESTAMP: { DBTIMESTAMP dbTimeStamp; if(pAccessor->GetValue(nCol, &dbTimeStamp)) { CTime tm(dbTimeStamp.year, dbTimeStamp.month, dbTimeStamp.day, dbTimeStamp.hour, dbTimeStamp.minute, dbTimeStamp.second); lValue = tm.GetTime(); } } break; case DBTYPE_DATE: { COleDateTime dt(*((DATE*)pAccessor->GetValue(nCol))); lValue = dt.GetYear() * 10000 + dt.GetMonth() * 10000 + dt.GetDay(); } break; case DBTYPE_DBTIME: { DBTIME dbTime; if(pAccessor->GetValue(nCol, &dbTime)) { dt.SetTime(dbTime.hour, dbTime.minute, dbTime.second); vt = COleVariant(dt); } } break; case DBTYPE_CY: { COleCurrency cy(*((CURRENCY*)pAccessor->GetValue(nCol))); vt = COleVariant(cy); } break; case DBTYPE_IUNKNOWN: { ISequentialStream* pStream = *(ISequentialStream**)pAccessor->GetValue(nCol); if (pStream != NULL ) { CString str; unsigned long lRead = 0; unsigned long lReadThis = 0; CByteArray ayBytes; BYTE szBuffer[4096]; BYTE* pByte = NULL; do { pStream->Read(szBuffer, 4096, &lReadThis); if (lReadThis > 0) { ayBytes.SetSize(lRead + lReadThis); pByte = ayBytes.GetData(); memcpy(pByte + lRead, szBuffer, lReadThis); lRead += lReadThis; } } while (lReadThis == 4096); ayBytes.SetSize(lRead); vt = ayBytes; } } break; case DBTYPE_NULL: case DBTYPE_EMPTY: default: break; } }