sql server2000表中的一个字段存储text类型数据,格式为每个数据间隔一个空格,即"3.0 4.4 5.9 6....."。现在自己封装一个getchunk函数,如下:
BOOL CADORecordset::GetChunk(FieldPtr pField, LPVOID lpData)
{
long lngSize, lngOffSet = 0;
_variant_t varChunk;
UCHAR chData;
HRESULT hr;
long lBytesCopied = 0; lngSize = pField->ActualSize;
while(lngOffSet < lngSize)
{
varChunk = pField->GetChunk(ChunkSize);
for(long lIndex = 0; lIndex <= (ChunkSize - 1); lIndex++)
{
hr= SafeArrayGetElement(varChunk.parray, &lIndex, &chData);
if(SUCCEEDED(hr))
{
hr = SafeArrayPutElement((SAFEARRAY FAR*)Data, &lBytesCopied ,&chData);
((UCHAR*)lpData)[lBytesCopied] = chData;
lBytesCopied++;
}
else
break;
}
lngOffSet += ChunkSize;
}
lngOffSet = 0;
return TRUE;
}
调试时发现到varChunk = pField->GetChunk(ChunkSize);时还是正确的,varChunk中保存了"3.0 4.4 5.9 6....."内容,但是SafeArrayGetElement(varChunk.parray, &lIndex, &chData);这句返回的hr为空。有大侠知道错在那里吗?
BOOL CADORecordset::GetChunk(FieldPtr pField, LPVOID lpData)
{
long lngSize, lngOffSet = 0;
_variant_t varChunk;
UCHAR chData;
HRESULT hr;
long lBytesCopied = 0; lngSize = pField->ActualSize;
while(lngOffSet < lngSize)
{
varChunk = pField->GetChunk(ChunkSize);
for(long lIndex = 0; lIndex <= (ChunkSize - 1); lIndex++)
{
hr= SafeArrayGetElement(varChunk.parray, &lIndex, &chData);
if(SUCCEEDED(hr))
{
hr = SafeArrayPutElement((SAFEARRAY FAR*)Data, &lBytesCopied ,&chData);
((UCHAR*)lpData)[lBytesCopied] = chData;
lBytesCopied++;
}
else
break;
}
lngOffSet += ChunkSize;
}
lngOffSet = 0;
return TRUE;
}
调试时发现到varChunk = pField->GetChunk(ChunkSize);时还是正确的,varChunk中保存了"3.0 4.4 5.9 6....."内容,但是SafeArrayGetElement(varChunk.parray, &lIndex, &chData);这句返回的hr为空。有大侠知道错在那里吗?
我认为你应该把
hr = SafeArrayPutElement((SAFEARRAY FAR*)Data, &lBytesCopied ,&chData);
这一句去掉
if(char *pBuffer = new char[ChunkSize+1]) ///重新申请必要的存储空间
{
char *pBuf = NULL;
SafeArrayAccessData(varBLOB.parray,(void **)&pBuf);
memcpy(pBuffer,pBuf,ChunkSize); ///复制数据到缓冲区m_pBMPBuffer
SafeArrayUnaccessData (varBLOB.parray);
((UCHAR*)lpData)[lBytesCopied] = pBuf;
lBytesCopied++;
}
To kyh77:试过了。在程序中
hr = SafeArrayAccessData(varBLOB.parray,(void **)&pBuf);
if (FAILED(hr))
break;
发现返回的hr还是不行,直接就break了。
是不是text类型的数据根本就不用GetChunk,直接就可以读到_variant_t类型的变量中
for (long lIndex = 0; lIndex <= (ChunkSize - 1); lIndex++)
{
hr= SafeArrayGetElement(varChunk.parray, &lIndex, &chData);
if (SUCCEEDED(hr))
{
// Take BYTE by BYTE and advance Memory Location
// hr = SafeArrayPutElement((SAFEARRAY FAR*)lpData, &lBytesCopied ,&chData);
((UCHAR*)lpData)[lBytesCopied] = chData;
lBytesCopied++;
}
else
break;
}// hr = SafeArrayPutElement((SAFEARRAY FAR*)lpData, &lBytesCopied ,&chData);
去掉这个话!如果我没有猜错的话,你的这个类是Carlos Antollini 写的吧!
这个类我也帮他改了些!
他的那套现在只支持CLIENT游标,现在我给他改一个SERVER游标的功能!
hr= SafeArrayGetElement(varChunk.parray, &lIndex, &chData);这句返回的hr无效,所以直接就break了
for(long lIndex = 0; lIndex <= (ChunkSize - 1); lIndex++)之间加入
if (varChunk.vt != (VT_ARRAY | VT_UI1))
{
return FALSE;
}
发现varChunk.vt != (VT_ARRAY | VT_UI1),函数在此返回。这是啥原因
int n = 5;
CString type = "fault";
char buff[3000];
CString strQuery;
strQuery.Format("select * from Alarm where address = %d and value = %s", n, type);
if(!m_AdoConnection.IsOpen()) //数据库是否打开
OpenDatabase();
CADORecordset* pRecord = new CADORecordset(&m_AdoConnection);//创建记录集
pRecord->Open((LPCTSTR)strQuery, CADORecordset::openQuery); // 返回特定的记录
if(pRecord->GetChunk("value", (char*)(LPVOID)buff)) // 读取返回记录中的录波数据
......
程序调用的GetChunk函数定义如下:
BOOL CADORecordset::GetChunk(LPCTSTR lpFieldName, LPVOID lpData)
{
FieldPtr pField = m_pRecordset->Fields->GetItem(lpFieldName);
return GetChunk(pField, lpData);
}
GetChunk(pField, lpData);函数就是出问题的函数。
BYTE *data;
//step 2.
data = new BYTE[size];
//step 3.
CYourADOClass->GetChunk("XXX", (LPVOID)data);
//step 4.
delete data
我看Carlos Antollini的帖子中有appendchunk和getchunk的例子,如下://Sample of AppendChunck
prs.AddNew();
prs.SetFieldValue("ID", 5);
prs.SetFieldValue("Description", "Client 05");
prs.SetFieldValue("Checker", 1);
prs.AppendChunk("Document",
"This Document is the story of Bob and his Friends...", 37);
prs.Update();//Sample of GetChunck
char data[1024];
prs.GetChunk("Document", (LPVOID)&data);