Jump to content
  • Advertisement
Sign in to follow this  
JonW

OLE DB -- Reading BLOBs

This topic is 3684 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi, I'm trying to read a BLOB column from an Access database using the basic Windows OLE DB API. I bind to the column and request an ISequentialStream interface for streaming in the data. I am having a couple issues, which are probably related: 1.) The first row read in gets an ISequentialStream pointer correctly, but attempting to read from it results in 0 bytes returned from ISequentialStream::Read. 2.) The second row has an undocumented HRESULT of 0x8000ffff returned from IRowset::GetNextRows (no matter what table I read from, or what the query is), and the rows read is equal to 0. Here is the code:
void CAreaDb::QueryRecordset (void)
{
	// Get the OLE DB session object
	IDBCreateSession *pIDBCreateSession;
	m_pIDBInitialize->QueryInterface(IID_IDBCreateSession, (void**)&pIDBCreateSession);

	// Create the session, getting an interface for command creation
	IDBCreateCommand *pIDBCreateCommand;
	pIDBCreateSession->CreateSession(NULL, IID_IDBCreateCommand, (IUnknown**)&pIDBCreateCommand);
	pIDBCreateSession->Release();

	// Create the command object
	ICommandText* pICommandText;
	pIDBCreateCommand->CreateCommand(NULL, IID_ICommandText, (IUnknown**)&pICommandText);
	pIDBCreateCommand->Release();

	// Set the command text as well as its language (SQL)
	pICommandText->SetCommandText(DBGUID_DBSQL, L"SELECT GDO_Geometry FROM d02_rest_area");

	// Execute the command
	LONG cRowsAffected;
	IRowset *pIRowset;
	pICommandText->Execute(NULL, IID_IRowset, NULL, &cRowsAffected, (IUnknown**)&pIRowset);
	pICommandText->Release();

	// Create the bindings from columns to offsets in the row value buffer
	DBBINDING binding;
	binding.iOrdinal = 1;
	binding.obValue = 0;
	binding.obLength = 0;
	binding.obStatus = sizeof(IUnknown*);
	binding.pTypeInfo = NULL;
	binding.pObject = NULL;
	binding.pBindExt = NULL;
	binding.dwPart = DBPART_VALUE | DBPART_STATUS;
	binding.dwMemOwner = DBMEMOWNER_CLIENTOWNED;
	binding.eParamIO = DBPARAMIO_NOTPARAM;
	binding.dwFlags = 0;
	binding.bPrecision = 0;
	binding.bScale = 0;
	binding.cbMaxLen = 0;
	binding.wType = DBTYPE_IUNKNOWN;

	// Ask the provider to return an ISequentialStream interface for reading
	DBOBJECT ObjectStruct;
	ObjectStruct.dwFlags = STGM_READ;
	ObjectStruct.iid = IID_ISequentialStream;
	binding.pObject = &ObjectStruct;

	// Create the accessor
	IAccessor *pIAccessor;
	HACCESSOR hAccessor;
	pIRowset->QueryInterface(IID_IAccessor, (void**)&pIAccessor);

	pIAccessor->CreateAccessor(DBACCESSOR_ROWDATA, 1, &binding, sizeof(IUnknown*) + sizeof(ULONG), &hAccessor, NULL);

	while (1)
	{
		// Get the next row handle
		HROW hRows[1];
		ULONG nRowsObtained;
		HROW *pRow = &hRows[0];

		// ERROR HERE!!!  Weird error on second pass through the loop
		HRESULT hr = pIRowset->GetNextRows(0, 0, 1, &nRowsObtained, &pRow);
		if (FAILED(hr))
			break;

		// All done -- there are no more rows left to get
		if (nRowsObtained == 0)
			return False;

		// Buffer of values read from the row
		char byRowValues[sizeof(IUnknown*) + sizeof(ULONG)];

		pIRowset->GetData(hRows[0], hAccessor, byRowValues);

		// HERE IS WHERE WE WOULD READ FROM THE ISequentialStream NOW
		// IN byRowValues; HOWEVER ISequentialStream::Read() RETURNS 0 BYTES

		// Release row handles
		pIRowset->ReleaseRows(nRowsObtained, hRows, NULL, NULL, NULL);
	}
}


This is some test code I put together, I don't have the problem with any rows that contain just basic values--its only when I bind to the BLOB column (an OLE Object containing binary data). I've been trying to figure this out for a long time! Any thoughts are greatly appreciated. Thanks!

Share this post


Link to post
Share on other sites
Advertisement
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!