Можно ли прочитать BLOB из oracle через OLE DB?
От: andrei_akm  
Дата: 22.12.08 13:14
Оценка:
На машине локально установлен oracle сервер 9.2.0.1.0. Система Windows XP. В студии 2005 на с++ пишу проект для работы с oracle через OLE DB. Все работает, КРОМЕ: не могу прочитать блоб.

Код стандартный:

hr = m_pICommandText->SetCommandText(DBGUID_DEFAULT, "SELECT bfield FROM tbl WHERE rowid=0");
hr = m_pICommandText->Execute(NULL, IID_IRowset, NULL, NULL, (IUnknown**)&m_pQrIRowset);
hr = m_pQrIRowset->QueryInterface(IID_IAccessor, (void**)&m_pQrIAccessor);

DBBINDSTATUS rgStatus[1];
DBOBJECT ObjectStruct;
ULONG ulbindstatus;
ULONG cRowsObtained = 0;
UINT cbRow = sizeof(IUnknown*) + sizeof(ULONG);
m_pBlobRow = new BYTE[cbRow];

hr = m_pQrIRowset->GetNextRows(NULL, 0, 1, &cRowsObtained, &m_rghQrRows);

ObjectStruct.dwFlags = STGM_READ;
ObjectStruct.iid = IID_ISequentialStream;

m_prgQrBindings[0].iOrdinal = 1;
m_prgQrBindings[0].obValue = 0;
m_prgQrBindings[0].obLength = 0;
m_prgQrBindings[0].obStatus = sizeof(IUnknown*);
m_prgQrBindings[0].pTypeInfo = NULL;
m_prgQrBindings[0].pObject = &ObjectStruct;
m_prgQrBindings[0].pBindExt = NULL;
m_prgQrBindings[0].dwPart = DBPART_VALUE | DBPART_STATUS;
m_prgQrBindings[0].dwMemOwner = DBMEMOWNER_CLIENTOWNED;
m_prgQrBindings[0].eParamIO = DBPARAMIO_NOTPARAM;
m_prgQrBindings[0].cbMaxLen = 0;
m_prgQrBindings[0].dwFlags = 0;
m_prgQrBindings[0].wType = DBTYPE_IUNKNOWN;
m_prgQrBindings[0].bPrecision = 0;
m_prgQrBindings[0].bScale = 0;

hr = m_pQrIAccessor->CreateAccessor(DBACCESSOR_ROWDATA, 1, m_prgQrBindings, sizeof(IUnknown*) + sizeof(ULONG), &m_hQrAccessor, rgStatus);
hr = m_pQrIRowset->GetData(m_rghQrRows[0], m_hQrAccessor, m_pBlobRow);

m_BlobReadStatus = (ULONG)((BYTE*)m_pBlobRow)[m_prgQrBindings[0].obStatus];
m_pBlobISequentialStream = *((ISequentialStream**)(m_pBlobRow + (m_prgQrBindings[0]).obValue));

Проблема в том, что m_BlobReadStatus всегда возвращается DBSTATUS_S_ISNULL и соответственно m_pBlobISequentialStream — некорректный указатель.
Хотя поле не NULL и содержит правильные данные.

SOS!!!
Re: Можно ли прочитать BLOB из oracle через OLE DB?
От: LuciferArh Россия  
Дата: 22.12.08 13:57
Оценка:
Здравствуйте, andrei_akm, Вы писали:

_>Проблема в том, что m_BlobReadStatus всегда возвращается DBSTATUS_S_ISNULL и соответственно m_pBlobISequentialStream — некорректный указатель.

_>Хотя поле не NULL и содержит правильные данные.

Провайдер от Microsoft? Смени на Oracle и проверь... Должно работать нормально.
Re[2]: Можно ли прочитать BLOB из oracle через OLE DB?
От: andrei_akm  
Дата: 22.12.08 14:35
Оценка:
Здравствуйте, LuciferArh, Вы писали:

LA>Здравствуйте, andrei_akm, Вы писали:


_>>Проблема в том, что m_BlobReadStatus всегда возвращается DBSTATUS_S_ISNULL и соответственно m_pBlobISequentialStream — некорректный указатель.

_>>Хотя поле не NULL и содержит правильные данные.

LA>Провайдер от Microsoft? Смени на Oracle и проверь... Должно работать нормально.


Но я ведь установил на машину Oracle сервер (следовательно, и клиент), значит, и оракловый OLE DB. Я по аутпуту смотрел, грузятся оракловые dllи : D:\oracle\ora92\bin\OraOLEDB.dll и т.п.
Включил оракловую трассу, там такое:
TID: eac (ENTRY) COracleCommand::SetProperties(1, 503f1c8)
TID: eac (EXIT) COracleCommand::SetProperties(hr=0): 3287
TID: eac (ENTRY) COracleCommand::SetCommandText(c8b521fb, 11ce5cf3)
TID: eac (EXIT) COracleCommand::SetCommandText(hr=0): 2842
TID: eac (ENTRY) COracleCommand::Execute(0, 208878204, 11ce2a1c, aa00e5ad, 3d774400)
TID: eac (EXIT) COracleCommand::Execute(hr=0): 2504
TID: eac (ENTRY) IRowsetOracleImpl::GetNextRows(0, 0, 1, 503f4fc, 18cc058)
TID: eac (EXIT) COracleRowset::GetNextRows(hr=0): 1938
TID: eac (ENTRY) IAccessorOracleImpl::CreateAccessor(2, 1, 18cc064, 8, 18cc060, 503f530)
TID: eac (ENTRY) IRowsetInfoImpl::GetProperties(1, 503f16c, 503f158, 503f14c)
TID: eac (EXIT) IRowsetInfoImpl::GetProperties(hr=0): 6439
TID: eac (EXIT) CreateAccessor(hr=0): 747
TID: eac (ENTRY) IRowsetOracleImpl::GetData(1, 5842e60, 186c8c8)
TID: eac (ENTRY) IRowsetInfoImpl::GetProperties(1, 503f0e4, 503f0d0, 503f0c4)
TID: eac (EXIT) IRowsetInfoImpl::GetProperties(hr=0): 6439
TID: eac (EXIT) COracleRowset::GetData(hr=0): 1451
Re[3]: Можно ли прочитать BLOB из oracle через OLE DB?
От: LuciferArh Россия  
Дата: 22.12.08 15:37
Оценка:
Здравствуйте, andrei_akm, Вы писали:

_>Но я ведь установил на машину Oracle сервер (следовательно, и клиент), значит, и оракловый OLE DB. Я по аутпуту смотрел, грузятся оракловые dllи : D:\oracle\ora92\bin\OraOLEDB.dll и т.п.


Это ни о чем не говорит. Строку подключения — в студию. Оракловые DLL будут грузиться в любом случае. Весь фокус в том, как их провайдер обработает.
Re[4]: Можно ли прочитать BLOB из oracle через OLE DB?
От: andrei_akm  
Дата: 22.12.08 16:03
Оценка:
Здравствуйте, LuciferArh, Вы писали:

LA>Здравствуйте, andrei_akm, Вы писали:


_>>Но я ведь установил на машину Oracle сервер (следовательно, и клиент), значит, и оракловый OLE DB. Я по аутпуту смотрел, грузятся оракловые dllи : D:\oracle\ora92\bin\OraOLEDB.dll и т.п.


LA>Это ни о чем не говорит. Строку подключения — в студию. Оракловые DLL будут грузиться в любом случае. Весь фокус в том, как их провайдер обработает.


Эээ...
Ну в общем подключаюсь тоже стандартно:

HRESULT hr = S_OK;
IRowsetChange* pIRowsetChange = NULL;

IDBProperties* pIDBProperties = NULL;
const ULONG cPropSets = 1;
const ULONG cProperties = 3;
DBPROPSET rgPropSets[cPropSets];
DBPROP rgProperties[cProperties];
const ULONG cLOGProperties = 3;
DBPROP rgLOGProperties[cLOGProperties];
const ULONG cCMPropSets = 1;
const ULONG cCMProperties = 1;
IDBCreateCommand* pCMIDBCreateCommand = NULL;
ICommandProperties* pCMICommandProperties = NULL;
DBPROPSET rgCMPropSets[cCMPropSets];
DBPROP rgCMProperties[cCMProperties];

for(ULONG i = 0; i < cLOGProperties; i++) VariantInit(&rgLOGProperties[i].vValue);

rgLOGProperties[0].dwPropertyID = DBPROP_INIT_DATASOURCE;
rgLOGProperties[0].vValue.vt = VT_BSTR;
rgLOGProperties[0].vValue.bstrVal = SysAllocString(database);
rgLOGProperties[0].dwOptions = DBPROPOPTIONS_REQUIRED;
rgLOGProperties[0].colid = DB_NULLID;

rgLOGProperties[1].dwPropertyID = DBPROP_AUTH_USERID;
rgLOGProperties[1].vValue.vt = VT_BSTR;
rgLOGProperties[1].vValue.bstrVal= SysAllocString(user);
rgLOGProperties[1].dwOptions = DBPROPOPTIONS_REQUIRED;
rgLOGProperties[1].colid = DB_NULLID;

rgLOGProperties[2].dwPropertyID = DBPROP_AUTH_PASSWORD;
rgLOGProperties[2].vValue.vt = VT_BSTR;
rgLOGProperties[2].vValue.bstrVal= SysAllocString(password);
rgLOGProperties[2].dwOptions = DBPROPOPTIONS_REQUIRED;
rgLOGProperties[2].colid = DB_NULLID;

rgPropSets[0].cProperties = cLOGProperties;
rgPropSets[0].rgProperties = rgLOGProperties;

hr = CoCreateInstance(CLSID_OraOLEDB, NULL, CLSCTX_INPROC_SERVER, IID_IDBInitialize, (void**)&m_pIDBInitialize);
hr = m_pIDBInitialize->QueryInterface(IID_IDBProperties, (void **)&pIDBProperties);
hr = pIDBProperties->SetProperties(cPropSets, rgPropSets);
hr = m_pIDBInitialize->Initialize();
hr = m_pIDBInitialize->QueryInterface(IID_IDBCreateSession, (void **)&m_pIDBCreateSession);
hr = m_pIDBCreateSession->CreateSession(NULL, IID_IDBCreateCommand, (IUnknown**)&pCMIDBCreateCommand);
hr = pCMIDBCreateCommand->CreateCommand(NULL, IID_ICommandText, (IUnknown**)&m_pICommandText);

rgCMPropSets[0].guidPropertySet = DBPROPSET_ROWSET;
rgCMPropSets[0].cProperties = cCMProperties;
rgCMPropSets[0].rgProperties = rgCMProperties;

rgCMPropSets[0].rgProperties[0].dwPropertyID = DBPROP_UPDATABILITY;
rgCMPropSets[0].rgProperties[0].dwOptions = DBPROPOPTIONS_REQUIRED;
rgCMPropSets[0].rgProperties[0].dwStatus = DBPROPSTATUS_OK;
rgCMPropSets[0].rgProperties[0].colid = DB_NULLID;
rgCMPropSets[0].rgProperties[0].vValue.vt = VT_I4;
V_I4(&rgCMPropSets[0].rgProperties[0].vValue) = DBPROPVAL_UP_CHANGE;

hr = m_pICommandText->QueryInterface(IID_ICommandProperties, (void **)&pCMICommandProperties);
hr = pCMICommandProperties->SetProperties(cCMPropSets, rgCMPropSets);

SAFE_RELEASE(pIDBProperties);
SAFE_RELEASE(pCMIDBCreateCommand);

Re: Можно ли прочитать BLOB из oracle через OLE DB?
От: ikogovuk Россия  
Дата: 23.12.08 21:08
Оценка:
Здравствуйте, andrei_akm, Вы писали:

_>На машине локально установлен oracle сервер 9.2.0.1.0. Система Windows XP. В студии 2005 на с++ пишу проект для работы с oracle через OLE DB. Все работает, КРОМЕ: не могу прочитать блоб.


Нужно использовать провайлер от Oracle 11g, желательно последней версии.
Остальные работу с блобами не поддерживают! Это точно, сам мозг сушил долго с этим вопросом.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.