OLEDB:获取SQL Server CE表的列元数据的最快方法是什么,而不选择任何行?

时间:2012-01-12 20:27:12

标签: sql-server sql-server-ce oledb

我必须将OLE DB与SQL Server CE一起使用。我的任务是获取表中所有列的元数据。

一种方法是选择任何行的所有字段,然后从结果行集中获取IColumnInfo。但是,这是以选择行为代价完成的。

我的问题 - 它是最快的方式还是有更好的方法来掌握表格中所有列的DBCOLUMNINFO个对象?

2 个答案:

答案 0 :(得分:3)

您可以在INFORMATION_SCHEMA上使用SELECT语句来提取特定表的COLUMN信息:

SELECT *
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = ?

然而,在OLEDB中有一个IDBSchemaRowset可以快得多。我已经整理了一个小的C ++代码示例,它显示了打开OLEDB连接(OpenDatabase)并使用IRowset(GetSchemaColumns)提取列信息。您需要添加IRowset返回(运行)的结果处理:

#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 :(得分:1)

如果您想避免选择行,请使用where 1 = 0作为where子句。

您也可以使用INFORMATION_SCHEMA表。

Microsoft文档:Information Schema (SQL Server Compact)