I'm going to assume SQL Server CE 3.0/3.1 but, for your reference, here are provider strings I'm aware of:
- SQL Server CE 3.0 / 3.1 - Microsoft.SQLLITE.MOBILE.OLEDB.3.0
- SQL Server CE 3.5 - Microsoft.SQLSERVER.CE.OLEDB.3.5
Also, I will be providing you with two code examples:
- ICommandText on "SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES"
- IDBSchemaRowset on DBSCHEMA_TABLES
I'm providing you the samples as C++ console application and have used ATL to make the code short. The code is complete and working but does not include the necessary error checking of the HRESULT hr.
Here's the C++ console application sample for querying a SQL Server CE 3.0/3.1 database for executing "SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES" using ICommandText and IRowset:
#include <stdio.h>
#include <tchar.h>
#include <windows.h>
#include <oledb.h>
#include <atlbase.h>
int _tmain(int argc, _TCHAR* argv[])
{
HRESULT hr = S_OK;
hr = CoInitializeEx(NULL, COINIT_MULTITHREADED);
// Connect to SQL Server.
CComPtr<IDBInitialize> spIDBInitialize;
hr = spIDBInitialize.CoCreateInstance(OLESTR("Microsoft.SQLLITE.MOBILE.OLEDB.3.0"));
CComPtr<IDBProperties> spIDBProperties;
hr = spIDBInitialize->QueryInterface(&spIDBProperties);
CComVariant varDataSource(OLESTR("InsertYourSampleDatabase.SDF"));
DBPROP prop = { DBPROP_INIT_DATASOURCE, DBPROPOPTIONS_REQUIRED, 0, DB_NULLID, varDataSource };
DBPROPSET propSet = {&prop, 1, DBPROPSET_DBINIT};
hr = spIDBProperties->SetProperties(1, &propSet);
spIDBProperties = NULL;
hr = spIDBInitialize->Initialize();
// Execute the query.
CComPtr<IDBCreateSession> spIDBCreateSession;
hr = spIDBInitialize->QueryInterface(&spIDBCreateSession);
CComPtr<IDBCreateCommand> spIDBCreateCommand;
hr = spIDBCreateSession->CreateSession(NULL, IID_IDBCreateCommand, (IUnknown**) &spIDBCreateCommand);
spIDBCreateSession = NULL;
CComPtr<ICommandText> spICommandText;
hr = spIDBCreateCommand->CreateCommand(NULL, IID_ICommandText, (IUnknown**) &spICommandText);
spIDBCreateCommand = NULL;
hr = spICommandText->SetCommandText(DBGUID_SQL, OLESTR("SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES"));
DBROWCOUNT cRowsAffected = 0;
CComPtr<IRowset> spIRowset;
hr = spICommandText->Execute(NULL, IID_IRowset, NULL, &cRowsAffected, (IUnknown**) &spIRowset);
spICommandText = NULL;
// Retrieve records.
HROW hRow = NULL;
HROW *rghRow = &hRow;
DBCOUNTITEM cRowsObtained = 0;
hr = spIRowset->GetNextRows(DB_NULL_HCHAPTER, 0, 1, &cRowsObtained, &rghRow);
while (hr == S_OK && cRowsObtained == 1)
{
// Fetch the TABLE_NAME field.
struct
{
DBSTATUS dbTableNameStatus;
ULONG nTableNameLength;
WCHAR szTableName[128 + 1];
} data = {0};
DBBINDING Binding = {0};
Binding.iOrdinal = 1;
Binding.obValue = sizeof(DBSTATUS) + sizeof(ULONG);
Binding.obLength = sizeof(DBSTATUS);
Binding.obStatus = 0;
Binding.pTypeInfo = NULL;
Binding.pObject = NULL;
Binding.pBindExt = NULL;
Binding.dwPart = DBPART_STATUS | DBPART_LENGTH | DBPART_VALUE;
Binding.dwMemOwner = DBMEMOWNER_CLIENTOWNED;
Binding.eParamIO = DBPARAMIO_NOTPARAM;
Binding.cbMaxLen = (128 + 1) * sizeof(WCHAR);
Binding.wType = DBTYPE_WSTR;
Binding.dwFlags = 0;
Binding.bPrecision = 0;
Binding.bScale = 0;
CComPtr<IAccessor> spIAccessor;
hr = spIRowset->QueryInterface(IID_IAccessor, (void**) &spIAccessor);
HACCESSOR hAccessor = NULL;
hr = spIAccessor->CreateAccessor(DBACCESSOR_ROWDATA, 1, &Binding, 0, &hAccessor, NULL);
hr = spIRowset->GetData(hRow, hAccessor, &data);
DBREFCOUNT cRefCount = 0;
hr = spIAccessor->ReleaseAccessor(hAccessor, &cRefCount);
spIAccessor = NULL;
// @@TODO: Do something with data.szTableName and data.nTableNameLength
_tprintf(_T("%s\n"), data.szTableName);
// Fetch next row of data.
hr = spIRowset->ReleaseRows(1, rghRow, NULL, NULL, NULL);
cRowsObtained = 0;
hr = spIRowset->GetNextRows(DB_NULL_HCHAPTER, 0, 1, &cRowsObtained, &rghRow);
}
// Release everything
spIRowset = NULL;
spIDBInitialize = NULL;
CoUninitialize();
return 0;
}
Here's the C++ console application sample for querying a SQL Server CE 3.0/3.1 database for browsing the tables using IDBSchemaRowset and IRowset (note that TABLE_NAME is now at iOrdinal 3 instead of 1):
#include <stdio.h>
#include <tchar.h>
#include <windows.h>
#include <oledb.h>
#include <atlbase.h>
int _tmain(int argc, _TCHAR* argv[])
{
HRESULT hr = S_OK;
hr = CoInitializeEx(NULL, COINIT_MULTITHREADED);
// Connect to SQL Server.
CComPtr<IDBInitialize> spIDBInitialize;
hr = spIDBInitialize.CoCreateInstance(OLESTR("Microsoft.SQLLITE.MOBILE.OLEDB.3.0"));
CComPtr<IDBProperties> spIDBProperties;
hr = spIDBInitialize->QueryInterface(&spIDBProperties);
CComVariant varDataSource(OLESTR("InsertYourSampleDatabase.SDF"));
DBPROP prop = { DBPROP_INIT_DATASOURCE, DBPROPOPTIONS_REQUIRED, 0, DB_NULLID, varDataSource };
DBPROPSET propSet = {&prop, 1, DBPROPSET_DBINIT};
hr = spIDBProperties->SetProperties(1, &propSet);
spIDBProperties = NULL;
hr = spIDBInitialize->Initialize();
// Execute the query.
CComPtr<IDBCreateSession> spIDBCreateSession;
hr = spIDBInitialize->QueryInterface(&spIDBCreateSession);
CComPtr<IDBSchemaRowset> spIDBSchemaRowset;
hr = spIDBCreateSession->CreateSession(NULL, IID_IDBSchemaRowset, (IUnknown**) &spIDBSchemaRowset);
spIDBCreateSession = NULL;
CComVariant rgRestrictions[CRESTRICTIONS_DBSCHEMA_TABLES];
// rgRestrictions[2] = OLESTR("CENSUS"); TABLE_NAME restriction
rgRestrictions[3] = OLESTR("TABLE"); // TABLE_TYPE restriction
CComPtr<IRowset> spIRowset;
hr = spIDBSchemaRowset->GetRowset(NULL, DBSCHEMA_TABLES, CRESTRICTIONS_DBSCHEMA_TABLES, rgRestrictions, IID_IRowset, 0, NULL, (IUnknown**) &spIRowset);
spIDBSchemaRowset = NULL;
// Retrieve records.
HROW hRow = NULL;
HROW *rghRow = &hRow;
DBCOUNTITEM cRowsObtained = 0;
hr = spIRowset->GetNextRows(DB_NULL_HCHAPTER, 0, 1, &cRowsObtained, &rghRow);
while (hr == S_OK && cRowsObtained == 1)
{
// Fetch the TABLE_NAME field.
struct
{
DBSTATUS dbTableNameStatus;
ULONG nTableNameLength;
WCHAR szTableName[128 + 1];
} data = {0};
DBBINDING Binding = {0};
Binding.iOrdinal = 3;
Binding.obValue = sizeof(DBSTATUS) + sizeof(ULONG);
Binding.obLength = sizeof(DBSTATUS);
Binding.obStatus = 0;
Binding.pTypeInfo = NULL;
Binding.pObject = NULL;
Binding.pBindExt = NULL;
Binding.dwPart = DBPART_STATUS | DBPART_LENGTH | DBPART_VALUE;
Binding.dwMemOwner = DBMEMOWNER_CLIENTOWNED;
Binding.eParamIO = DBPARAMIO_NOTPARAM;
Binding.cbMaxLen = (128 + 1) * sizeof(WCHAR);
Binding.wType = DBTYPE_WSTR;
Binding.dwFlags = 0;
Binding.bPrecision = 0;
Binding.bScale = 0;
CComPtr<IAccessor> spIAccessor;
hr = spIRowset->QueryInterface(IID_IAccessor, (void**) &spIAccessor);
HACCESSOR hAccessor = NULL;
hr = spIAccessor->CreateAccessor(DBACCESSOR_ROWDATA, 1, &Binding, 0, &hAccessor, NULL);
hr = spIRowset->GetData(hRow, hAccessor, &data);
DBREFCOUNT cRefCount = 0;
hr = spIAccessor->ReleaseAccessor(hAccessor, &cRefCount);
spIAccessor = NULL;
// @@TODO: Do something with data.szTableName and data.nTableNameLength
_tprintf(_T("%s\n"), data.szTableName);
// Fetch next row of data.
hr = spIRowset->ReleaseRows(1, rghRow, NULL, NULL, NULL);
cRowsObtained = 0;
hr = spIRowset->GetNextRows(DB_NULL_HCHAPTER, 0, 1, &cRowsObtained, &rghRow);
}
// Release everything
spIRowset = NULL;
spIDBInitialize = NULL;
CoUninitialize();
return 0;
}