Необработанный код C ++ для отображения имен таблиц на компактном сервере SQL с использованием OLE DB - PullRequest
1 голос
/ 08 января 2012

Есть ли у кого-нибудь пример кода, в котором в файле базы данных отображаются имена всех пользовательских таблиц?

Меня не интересует код .NET, только C ++.

Я пытаюсь заставить OLE DB выполнить задачу - ракетостроение кажется детской игрой в сравнении.

Ответы [ 2 ]

4 голосов
/ 02 февраля 2012

Я собираюсь предположить, что SQL Server CE 3.0 / 3.1, но, для вашей справки, вот строки поставщика, о которых я знаю:

  • SQL Server CE 3.0 / 3.1 - Microsoft.SQLLITE.MOBILE.OLEDB.3.0
  • SQL Server CE 3.5 - Microsoft.SQLSERVER.CE.OLEDB.3.5

Кроме того, я предоставлю вам два примера кода:

  • ICommandText в «SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES»
  • IDBSchemaRowset в DBSCHEMA_TABLES

Я предоставляю вам примеры в виде консольного приложения C ++ и использую ATL длясделать код коротким.Код завершен и работает, но не включает необходимую проверку ошибок HRESULT hr.

Вот пример консольного приложения C ++ для запроса базы данных SQL Server CE 3.0 / 3.1 для выполнения «SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES»."использование ICommandText и 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;
}

Вот пример консольного приложения C ++ для запроса базы данных SQL Server CE 3.0 / 3.1 для просмотра таблиц с использованием IDBSchemaRowset и IRowset (обратите внимание, что TABLE_NAME теперь находится в iOrdinal 3 вместо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;
}
0 голосов
/ 09 января 2012
SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES
...