Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 Помогите с SQLCE OLEDB ошибка в GetData  [new]
irigm
Member

Откуда:
Сообщений: 28
Помогите пожалуйста пишу для PDA + SQLCE пытаюсь написать небольшой Wrapper для проекта. При выборке из базы данных int,string работает а когда пытаюсь выбрать по больше полей вылетает ошибка памяти на функции pIRowset->GetData(rghRows[iRow], hAccessor, pRowValues);
DataBase=new MyDataBase(ApplicationPath()+L"Companies.sdf");
MyRowSet* rowSet=DataBase->ExecuteSQL(L"SELECT Id,Header,Phones FROM Companies where id=643");
rowSet->myGetData();
H
#ifndef MYOLEDBWRAPPER_H
#define MYOLEDBWRAPPER_H
// -----------------------------------------------------------------------------
#include <sqlce_oledb.h>
#include <sqlce_err.h>
#include <sqlce_sync.h>

#include <string>
using namespace std;
// -----------------------------------------------------------------------------
class MyRowSet
{
private:
	wstring strRow;
protected:
	IRowset*		pIRowset;
    IAccessor*		pIAccessor; // Pointer to the accessor
	HACCESSOR		hAccessor;  // Accessor handle
	DBBINDING*		pDBBindings;
	DBBINDSTATUS*	pDBBindStatus;
	DBCOLUMNINFO*   pColumnsInfo;
	OLECHAR*        pColumnStrings;
	BYTE*           pRowValues;
	ULONG			nCols;
    HROW            rghRows[1];// Row handles
    HROW*           pRows;   // Pointer to the row 

	//ULONG	cRowsObtained; // Number of rows obtained

	/*void myCreateDBBindings
	(
		ULONG nCols, // [in]
		DBCOLUMNINFO* pColumnsInfo, // [in]
		DBBINDING** ppDBBindings, // [out]
		BYTE** ppRowValues // [out]
	);*/
	void myCreateDBBindings
	(
		ULONG nCols,                 // [in]
		DBCOLUMNINFO* pColumnsInfo,  // [in]
		DBBINDING** ppDBBindings,    // [out]
		BYTE** ppRowValues           // [out]
	);
	HRESULT MyRowSet::myGetColumnsInfo
	(
		IRowset* pIRowset, // [in]
		ULONG* pnCols, // [out]
		DBCOLUMNINFO** ppColumnsInfo, // [out]
		OLECHAR** ppColumnStrings // [out]
	);
public:
	MyRowSet(IRowset* pIRowset);
	~MyRowSet();
	bool RestartPosition();
	bool getNextRow();

	BYTE* getData(ULONG nCol);
	wstring getDataString(ULONG	nCol);
	int getDataInt(ULONG nCol);

	//void printAllData();
	void myGetData();
};
// -----------------------------------------------------------------------------
class MyDataBase
{
private:
protected:
	IDBCreateSession *m_pIDBCreateSession;  // The IDBCreateSession interface
public:
	MyDataBase(wstring dbPath);
	~MyDataBase();
	MyRowSet* ExecuteSQL(wstring sql);
};
// -----------------------------------------------------------------------------
#endif
Cpp
#include "stdafx.h"
#include "MyOLEDBWrapper.h"
#include <iostream>

// -----------------------------------------------------------------------------
MyDataBase::MyDataBase(wstring dbPath)
{
	m_pIDBCreateSession=NULL;
    HRESULT			   	hr				= NOERROR;	// Error code reporting
	DBPROP				dbprop[1];					// property used in property set to initialize provider
	DBPROPSET			dbpropset[1];				// Property Set used to initialize provider

    IDBInitialize       *pIDBInitialize = NULL;		// Provider Interface Pointer
	IDBProperties       *pIDBProperties	= NULL;		// Provider Interface Pointer

	VariantInit(&dbprop[0].vValue);		

    // Create an instance of the OLE DB Provider
	//
	hr = CoCreateInstance(	CLSID_SQLSERVERCE_3_5, 0, 
							CLSCTX_INPROC_SERVER, 
							IID_IDBInitialize, 
							(void**)&pIDBInitialize);
	if(FAILED(hr))
	{
		goto Exit;
	}

	// Initialize a property with name of database
	//
    dbprop[0].dwPropertyID	= DBPROP_INIT_DATASOURCE;
	dbprop[0].dwOptions		= DBPROPOPTIONS_REQUIRED;
    dbprop[0].vValue.vt		= VT_BSTR;
    dbprop[0].vValue.bstrVal= SysAllocString(dbPath.c_str());
	if(NULL == dbprop[0].vValue.bstrVal)
	{
		hr = E_OUTOFMEMORY;
		goto Exit;
	}

	// Initialize the property set
	//
	dbpropset[0].guidPropertySet = DBPROPSET_DBINIT;
	dbpropset[0].rgProperties	 = dbprop;
	dbpropset[0].cProperties	 = sizeof(dbprop)/sizeof(dbprop[0]);

	//Set initialization properties.
	//
	hr = pIDBInitialize->QueryInterface(IID_IDBProperties, (void **)&pIDBProperties);
    if(FAILED(hr))
    {
		goto Exit;
    }

	// Sets properties in the Data Source and initialization property groups
	//
    hr = pIDBProperties->SetProperties(1, dbpropset); 
	if(FAILED(hr))
    {
		goto Exit;
    }

	// Initializes a data source object 
	//
	hr = pIDBInitialize->Initialize();
	if(FAILED(hr))
    {
		cout << "Unable to initialize IDBInitialize" << endl;
		switch  (hr)
		{
			case DB_S_ASYNCHRONOUS:
				cout << "DB_S_ASYNCHRONOUS" << endl;
			case DB_S_ERRORSOCCURRED:
				cout << "DB_S_ERRORSOCCURRED" << endl;
				break;
			case E_FAIL:
				cout << "E_FAIL" << endl;
				break;
			case E_OUTOFMEMORY:
				cout << "E_OUTOFMEMORY" << endl;
				break;
			case E_UNEXPECTED:
				cout << "E_UNEXPECTED" << endl;
				break;
			case DB_E_ALREADYINITIALIZED:
				cout << "DB_E_ALREADYINITIALIZED" << endl;
				break;
			case DB_E_CANCELED:
				cout << "DB_E_CANCELED" << endl;
				break;
			case DB_E_ERRORSOCCURRED:
				cout << "DB_E_ERRORSOCCURRED" << endl;
				break;
			case DB_SEC_E_AUTH_FAILED:
				cout << "DB_SEC_E_AUTH_FAILED" << endl;
				break;
			default:
				cout << " ????? " << endl;
				break;
		}	
		goto Exit;
    }

    // Get IDBCreateSession interface
    //
  	hr = pIDBInitialize->QueryInterface(IID_IDBCreateSession, (void**)&m_pIDBCreateSession);
	if(FAILED(hr))
	{
		goto Exit;
	}

Exit:
    // Clear Variant
    //
	VariantClear(&dbprop[0].vValue);

	// Release interfaces
	//
	if(pIDBProperties)
	{
		pIDBProperties->Release();
	}

    if (pIDBInitialize)
    {
        pIDBInitialize->Release();
    }
}
// -----------------------------------------------------------------------------
MyDataBase::~MyDataBase()
{
	if(m_pIDBCreateSession)
	{
		HRESULT        hr = NOERROR;
		IDBInitialize *pIDBInitialize = NULL;
		hr = m_pIDBCreateSession->QueryInterface(IID_IDBInitialize, (void **) &pIDBInitialize);
		if(SUCCEEDED(hr))
		{
			pIDBInitialize->Uninitialize();
			pIDBInitialize->Release();
		}
		m_pIDBCreateSession->Release();
	}
}
// -----------------------------------------------------------------------------
MyRowSet* MyDataBase::ExecuteSQL(wstring sql)
{
	if(m_pIDBCreateSession==NULL)return NULL;

	HRESULT hr=NOERROR;

	// Get IDBCreateCommand interface
	// Get the interface to create a command
	IDBCreateCommand   *pIDBCreateCommand  = NULL;
	hr = m_pIDBCreateSession->CreateSession(NULL, IID_IDBCreateCommand,(IUnknown**) &pIDBCreateCommand);
	if (FAILED(hr)) 
	{
		wprintf(L"FAILED");
		//goto Exit;
	}
	// Create the new command that uses parameters.
	ICommandText       *pICommandText      = NULL;
	hr = pIDBCreateCommand->CreateCommand(NULL, IID_ICommandText, (IUnknown**) &pICommandText);
	if (FAILED(hr))
	{
		wprintf(L"FAILED");
		//Send an error-specific message and do error handling.
		//goto Exit;
	}
	// Specify the command text using parameter markers in the query syntax.
	// We know that this command will return 1 row and one image column (Photo).
	hr = pICommandText->SetCommandText(DBGUID_DBSQL, sql.c_str());
	if (FAILED(hr))
	{
		wprintf(L"FAILED");
		//Send an error-specific message and do error handling.
		//goto Exit;
	}
	IRowset *pIRowset=NULL;
	hr = pICommandText->Execute(NULL, IID_IRowset, NULL, NULL, (IUnknown**) &pIRowset);
	if(FAILED(hr))
	{
		wprintf(L"FAILED");
		//goto Exit;
	}
	return new MyRowSet(pIRowset);
}
// *****************************************************************************
MyRowSet::MyRowSet(IRowset* pIRowset)
{
	this->pIRowset=pIRowset;

	HRESULT			hr				= NOERROR;
	pColumnsInfo	= NULL;
	pColumnStrings	= NULL;
    pRows = &rghRows[0];   // Pointer to the row 
                                           // handles
	pDBBindStatus = NULL;
    pDBBindings = NULL;

    // Get the description of the rowset for use in binding structure
    // creation.
    if (FAILED(myGetColumnsInfo(pIRowset, &nCols, &pColumnsInfo,&pColumnStrings)))
    {
        return;
    }

    // Create the binding structures.
    myCreateDBBindings(nCols, pColumnsInfo, &pDBBindings, &pRowValues);
    pDBBindStatus = new DBBINDSTATUS[nCols];

    // Create the accessor.
    hr=pIRowset->QueryInterface(IID_IAccessor, (void**) &pIAccessor);
	if (FAILED(hr)) return;
    hr=pIAccessor->CreateAccessor(DBACCESSOR_ROWDATA,nCols,pDBBindings,0,&hAccessor,pDBBindStatus);
    if (FAILED(hr)) return;
}
// -----------------------------------------------------------------------------
MyRowSet::~MyRowSet()
{
    // Release the accessor.
    pIAccessor->ReleaseAccessor(hAccessor, NULL);
    pIAccessor->Release();

    delete [] pDBBindings;
    delete [] pDBBindStatus;

	if(pColumnsInfo)
	{
		CoTaskMemFree(pColumnsInfo);
		pColumnsInfo = NULL;
	}
	if(pColumnStrings)
	{
		CoTaskMemFree(pColumnStrings);
		pColumnStrings = NULL;
	}

	pIRowset->Release();
}
 /********************************************************************
* Create binding structures from column information. Binding
* structures will be used to create an accessor that permits row value 
* retrieval.
********************************************************************/ 
void MyRowSet::myCreateDBBindings
(
    ULONG nCols,                 // [in]
    DBCOLUMNINFO* pColumnsInfo,  // [in]
    DBBINDING** ppDBBindings,    // [out]
    BYTE** ppRowValues           // [out]
)
{
    ULONG       nCol;
    ULONG       cbRow = 0;
    DBBINDING*  pDBBindings;
    BYTE*       pRowValues;

    pDBBindings = new DBBINDING[nCols];

    for (nCol = 0; nCol < nCols; nCol++)
        {
        pDBBindings[nCol].iOrdinal = nCol+1;
        pDBBindings[nCol].obValue = cbRow;
        pDBBindings[nCol].obLength = 0;
        pDBBindings[nCol].obStatus = 0;
        pDBBindings[nCol].pTypeInfo = NULL;
        pDBBindings[nCol].pObject = NULL;
        pDBBindings[nCol].pBindExt = NULL;
        pDBBindings[nCol].dwPart = DBPART_VALUE;
        pDBBindings[nCol].dwMemOwner = DBMEMOWNER_CLIENTOWNED;
        pDBBindings[nCol].eParamIO = DBPARAMIO_NOTPARAM;
        pDBBindings[nCol].cbMaxLen = pColumnsInfo[nCol].ulColumnSize;
        pDBBindings[nCol].dwFlags = 0;
		pDBBindings[nCol].wType=DBTYPE_WSTR;

        pDBBindings[nCol].bPrecision = pColumnsInfo[nCol].bPrecision;
        pDBBindings[nCol].bScale = pColumnsInfo[nCol].bScale;

        cbRow += pDBBindings[nCol].cbMaxLen;
        }

    pRowValues = new BYTE[cbRow];

    *ppDBBindings = pDBBindings;
    *ppRowValues = pRowValues;

    return;
}
// -----------------------------------------------------------------------------
bool MyRowSet::RestartPosition()
{
	return pIRowset->RestartPosition(0)==S_OK;
}
// -----------------------------------------------------------------------------
bool MyRowSet::getNextRow()
{
	ULONG	iRow; // Row count
	ULONG	cRowsObtained;
	if (FAILED(pIRowset->GetNextRows(0,0,1,&cRowsObtained,&pRows))) return false;
    if (cRowsObtained == 0) return false; // All completed; there are no more rows left to get.	
	for (iRow=0; iRow < cRowsObtained; iRow++)// Loop over rows obtained, getting data for each.
	{
		pIRowset->GetData(rghRows[iRow], hAccessor, pRowValues);
	}
	pIRowset->ReleaseRows(cRowsObtained, rghRows, NULL, NULL, NULL); //delete old
	return true;
}
// -----------------------------------------------------------------------------
BYTE* MyRowSet::getData(ULONG nCol)
{
	if(nCol>=nCols) return NULL;
	return &pRowValues[pDBBindings[nCol].obValue];
}
// -----------------------------------------------------------------------------
wstring MyRowSet::getDataString(ULONG nCol)
{
	if(nCol>=nCols) return L"";
	return (LPCWSTR)&pRowValues[pDBBindings[nCol].obValue];
}
// -----------------------------------------------------------------------------
int MyRowSet::getDataInt(ULONG nCol)
{
	if(nCol>=nCols) return 0;
	int* i=(int*)&pRowValues[pDBBindings[nCol].obValue];
	return *i;
}
// -----------------------------------------------------------------------------
//вывести все даные в консоль
void MyRowSet::myGetData()
{
	if(pIRowset==NULL) return;

	HRESULT			hr				= NOERROR;
    ULONG           nCols;
    DBCOLUMNINFO*   pColumnsInfo	= NULL;
    OLECHAR*        pColumnStrings	= NULL;
    ULONG           nCol;
    ULONG           cRowsObtained;         // Number of rows obtained
    ULONG           iRow;                  // Row count
    HROW            rghRows[1];// Row handles
    HROW*           pRows = &rghRows[0];   // Pointer to the row 
                                           // handles
    IAccessor*      pIAccessor;            // Pointer to the accessor
    HACCESSOR       hAccessor;             // Accessor handle
    DBBINDSTATUS*   pDBBindStatus = NULL;
    DBBINDING*      pDBBindings = NULL;
    BYTE*           pRowValues;

    // Get the description of the rowset for use in binding structure
    // creation.
    if (FAILED(myGetColumnsInfo(pIRowset, &nCols, &pColumnsInfo,&pColumnStrings)))
    {
        return;
    }

    // Create the binding structures.
    myCreateDBBindings(nCols, pColumnsInfo, &pDBBindings, &pRowValues);
    pDBBindStatus = new DBBINDSTATUS[nCols];

    // Create the accessor.
    hr=pIRowset->QueryInterface(IID_IAccessor, (void**) &pIAccessor);
	if (FAILED(hr)) return;
    hr=pIAccessor->CreateAccessor(DBACCESSOR_ROWDATA,nCols,pDBBindings,0,&hAccessor,pDBBindStatus);
    if (FAILED(hr)) return;



     // Process all the rows, NUMROWS_CHUNK rows at a time.
	int pos=0,count=0;
    while (TRUE)
    {
        hr=pIRowset->GetNextRows(0,0,1,&cRowsObtained,&pRows);
		if (FAILED(hr)) return;

        // All completed; there are no more rows left to get.
        if (cRowsObtained == 0) break;
		// Loop over rows obtained, getting data for each.
		for (iRow=0; iRow < cRowsObtained; iRow++)
		{
			pIRowset->GetData(rghRows[iRow], hAccessor, pRowValues);
			for (nCol = 0; nCol < nCols; nCol++)
			{
				wprintf((LPCWSTR)&pRowValues[pDBBindings[nCol].obValue]);
			}
		}
		count++;
        // Release row handles.
        pIRowset->ReleaseRows(cRowsObtained, rghRows, NULL, NULL, NULL);
	}  // End while

    // Release the accessor.
    pIAccessor->ReleaseAccessor(hAccessor, NULL);
    pIAccessor->Release();

    delete [] pDBBindings;
    delete [] pDBBindStatus;

	if(pColumnsInfo)
	{
		CoTaskMemFree(pColumnsInfo);
		pColumnsInfo = NULL;
	}
	if(pColumnStrings)
	{
		CoTaskMemFree(pColumnStrings);
		pColumnStrings = NULL;
	}
    return;
}
/********************************************************************
* Get the characteristics of the rowset (the ColumnsInfo interface).
********************************************************************/ 
HRESULT MyRowSet::myGetColumnsInfo
(
    IRowset*        pIRowset,        // [in]
    ULONG*          pnCols,          // [out]
    DBCOLUMNINFO**  ppColumnsInfo,   // [out]
    OLECHAR**       ppColumnStrings  // [out]
)
{
    IColumnsInfo*   pIColumnsInfo;
    HRESULT         hr;

    if (FAILED(pIRowset->QueryInterface(IID_IColumnsInfo, (void**) &pIColumnsInfo)))
	{
        cout<< "Query rowset interface for IColumnsInfo failed";
        return (E_FAIL);
	}

    hr = pIColumnsInfo->GetColumnInfo(pnCols, ppColumnsInfo, ppColumnStrings);
    if (FAILED(hr))
	{
        cout<< "GetColumnInfo failed.";
        *pnCols = 0;
	}

    pIColumnsInfo->Release();
    return (hr);
}
// -----------------------------------------------------------------------------
19 июн 09, 04:55    [7318512]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить