我必须将OLE DB与SQL Server CE一起使用。我的任务是获取表中所有列的元数据。
一种方法是选择任何行的所有字段,然后从结果行集中获取IColumnInfo
。但是,这是以选择行为代价完成的。
我的问题 - 它是最快的方式还是有更好的方法来掌握表格中所有列的DBCOLUMNINFO
个对象?
答案 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)