OLEDB: Какой самый быстрый способ получить метаданные столбца для таблицы SQL Server CE без выбора каких-либо строк? - PullRequest
1 голос
/ 13 января 2012

Я должен использовать OLE DB с SQL Server CE.Моя задача - получить метаданные по всем столбцам таблицы.

Один из способов сделать это - выбрать все поля любой строки и затем получить IColumnInfo из полученного набора строк.Тем не менее, это делается за счет выбора строки.

Мой вопрос - это самый быстрый способ или есть лучший способ закрепиться за объектами DBCOLUMNINFO для всех столбцов в таблице?

Ответы [ 2 ]

3 голосов
/ 13 января 2012

Вы можете использовать оператор SELECT в INFORMATION_SCHEMA для извлечения информации COLUMN для конкретной таблицы:

SELECT *
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = ?

Однако в OLEDB есть IDBSchemaRowset, который может быть намного быстрее.Я собрал небольшой пример кода C ++, который показывает открытие соединения OLEDB (OpenDatabase) и извлечение информации о столбце с помощью IRowset (GetSchemaColumns).Вам нужно добавить обработку результатов из возвращенного IRowset (Run):

#include <windows.h>
#include <atlbase.h>
#include <oleauto.h>
#include <oledb.h>

HRESULT OpenDatabase(LPOLESTR szPath, IDBInitialize **ppIDBInitialize)
{
    HRESULT hr = S_OK;
    CComPtr<IDBInitialize> spIDBInitialize;
    hr = spIDBInitialize.CoCreateInstance(OLESTR("Microsoft.SQLLITE.MOBILE.OLEDB.3.0"));
    CComPtr<IDBProperties> spIDBProperties;
    spIDBProperties = spIDBInitialize;
    CComVariant vDataSource(szPath);
    DBPROP dbProp = { DBPROP_INIT_DATASOURCE, DBPROPOPTIONS_REQUIRED, 0, DB_NULLID, vDataSource };
    DBPROPSET dbPropSet = { &dbProp, 1, DBPROPSET_DBINIT };
    hr = spIDBProperties->SetProperties(1, &dbPropSet);
    hr = spIDBInitialize->Initialize();
    *ppIDBInitialize = spIDBInitialize.Detach();
    return hr;
}

HRESULT GetSchemaColumns(IUnknown *pDataSource, LPOLESTR pTableName, IRowset **ppIRowset)
{
    HRESULT hr = S_OK;
    CComPtr<IDBCreateSession> spIDBCreateSession;
    hr = pDataSource->QueryInterface(IID_IDBCreateSession, (void**) &spIDBCreateSession);
    CComPtr<IDBCreateCommand> spIDBCreateCommand;
    hr = spIDBCreateSession->CreateSession(NULL, IID_IDBCreateCommand, (IUnknown**) &spIDBCreateCommand);
    CComPtr<IDBSchemaRowset> spIDBSchemaRowset;
    hr = spIDBCreateCommand->QueryInterface(IID_IDBSchemaRowset, (void**) &spIDBSchemaRowset);
    CComVariant vRestrictions[CRESTRICTIONS_DBSCHEMA_COLUMNS];
    vRestrictions[2] = pTableName;
    CComPtr<IRowset> spIRowset;
    hr = spIDBSchemaRowset->GetRowset(NULL, DBSCHEMA_COLUMNS, CRESTRICTIONS_DBSCHEMA_COLUMNS, vRestrictions, IID_IRowset, NULL, NULL, (IUnknown**) &spIRowset);
    *ppIRowset = spIRowset.Detach();
    return hr;
}

HRESULT Run()
{
    HRESULT hr = S_OK;
    CComPtr<IDBInitialize> spIDBInitialize;
    hr = OpenDatabase(OLESTR("MyDatabase.sdf"), &spIDBInitialize);
    CComPtr<IRowset> spIRowset;
    hr = GetSchemaColumns(spIDBInitialize, OLESTR("MyTableName"), &spIRowset);
    DBCOUNTITEM cRows = 0;
    HROW hRow = NULL;
    HROW *phRow = &hRow;
    hr = spIRowset->GetNextRows(DB_NULL_HCHAPTER, 0, 1, &cRows, &phRow);
    while (SUCCEEDED(hr) && cRows > 0)
    {
        // Do handling of a row fetched from INFORMATION_SCHEMA.COLUMN here
        // ...
        hr = spIRowset->ReleaseRows(1, phRow, NULL, NULL, NULL);
        hr = spIRowset->GetNextRows(DB_NULL_HCHAPTER, 0, 1, &cRows, &phRow);
    }
    return hr;
}
1 голос
/ 13 января 2012

Если вы хотите избежать выбора строк, используйте where 1 = 0 в качестве предложения where.

Вы также можете использовать таблицы INFORMATION_SCHEMA.

Документы Microsoft: Информационная схема (SQL Server Compact)

...