OLEDB Providers Enumeration
来源:互联网 发布:三维彩超数据计算男女 编辑:程序博客网 时间:2024/06/04 22:48
By: AdvanCode [2004-12-01]
Read: 3350 times
The question is: how can we get all OLEDB providers available? This could be done, relatively simply using VC++, but there aren't a simply solution for VB users. So, we'll try to make an ATL component to be used both in VC++ or VB projects.
There are at least 2 solutions for the problem - the first one is to use ADO and the other is using OLE DB interfaces.
Using ADO is simply to return an ADODB.Recordset containing all the informations. An example could be found here (Copyright 2002 Bob Beauchemin). Mainly, this is done like this (after you added ADO support):
STDMETHODIMP CGetProvRS::GetProvRS(VARIANT *pvRecordset){Recordset20Ptr spRs;ADORecordsetConstructionPtr spADOsCt;VariantInit(pvRecordset);CEnumerator cenum;HRESULT hr;// Root enumerator is the defaulthr = cenum.Open();if (FAILED(hr)) goto cleanup;hr = spRs.CreateInstance(__uuidof(Recordset));if (FAILED(hr))goto cleanup; hr = spRs->QueryInterface(__uuidof(ADORecordsetConstruction), (void **)&spADOsCt);if (FAILED(hr))goto cleanup;hr = spADOsCt->put_Rowset(cenum.m_spRowset);if (FAILED(hr))goto cleanup;pvRecordset->vt = VT_DISPATCH;pvRecordset->pdispVal = (IDispatch*)spRs.Detach();cleanup:cenum.Close();return hr;}
Doing so, the method is returning an ADODB.Recordset that can be used in VB applications, for instance. The names of the fields returned are:
col 0: size 4 type DBTYPE_UI4col 1: name SOURCES_NAME size 255 type DBTYPE_WSTRcol 2: name SOURCES_PARSENAME size 255 type DBTYPE_WSTRcol 3: name SOURCES_DESCRIPTION size 255 type DBTYPE_WSTRcol 4: name SOURCES_TYPE size 2 type DBTYPE_UI2col 5: name SOURCES_ISPARENT size 2 type DBTYPE_BOOLcol 6: name SOURCES_CLSID size 255 type DBTYPE_WSTR
All the details can be found here.
A VB example of using the component could be as below:
Dim rs As Recordset Dim provrs As New GetProvRS Dim i As Integer Set rs = provrs.GetProvRS() While Not rs.EOF For i = 0 To rs.Fields.Count - 1 Debug.Print "Field: " & rs(i).Name & " = " & rs(i).Value Next i Debug.Print rs.MoveNext Wend
The other solution is by using OLEDB interfaces, directly, as presented in "Teach Yourself Database Programming with Visual C++ 6 in 21 Days" (cap. 17), from Sams Publishing or this example from Microsoft KB (in italian).
Below, there is the source code for an ATL component that return all providers as variant-array, which is simply to use in VB. Create a new component using ATL COM AppWizard and add a new ATL object called "Providers". Include the libraries and the constants as below (in Providers.cpp):
#include <oledb.h>#include <oledberr.h>#include <MSDAGUID.H>typedef struct EnumProvidersRow{ UINT num; char SourceName[255]; char ParseName[255]; char SourceDesc[255]; USHORT SourceType; BOOL IsParent; char SourceCLSID[255];} ENUMPROVIDERSROW;#define COLS 7#define ROWS 10
Then add the following code in a new created method called GetProviders([out, retval] VARIANT* res):
STDMETHODIMP CProviders::GetProviders(VARIANT *res){// TODO: Add your implementation code here ISourcesRowset* pSrcRowset; IRowset* pRowset; IAccessor* pAccessor; HACCESSOR hAccessor; ENUMPROVIDERSROW Rows; DBBINDING Binding[COLS]; DBBINDSTATUS BindingStatus[COLS]; ULONG Feched; HROW* phRow = new HROW[ROWS]; ZeroMemory( &Binding[0], sizeof(DBBINDING) * COLS); HRESULT hr = CoCreateInstance(CLSID_OLEDB_ENUMERATOR, NULL, CLSCTX_INPROC_SERVER, IID_ISourcesRowset, (LPVOID*)&pSrcRowset); if( hr == S_OK ) { hr = pSrcRowset->GetSourcesRowset( NULL, IID_IRowset, 0, NULL, (LPUNKNOWN*)&pRowset); pSrcRowset->Release(); if( hr == S_OK ) { hr = pRowset->QueryInterface(IID_IAccessor, (LPVOID*)&pAccessor); if( hr == S_OK ) { Binding[0].iOrdinal = 0; Binding[0].obValue = offsetof(ENUMPROVIDERSROW, num); Binding[0].dwPart = DBPART_VALUE; Binding[0].dwMemOwner = DBMEMOWNER_CLIENTOWNED; Binding[0].eParamIO = DBPARAMIO_NOTPARAM; Binding[0].wType = DBTYPE_UI4; Binding[1].iOrdinal = 1; Binding[1].obValue = offsetof(ENUMPROVIDERSROW, SourceName); Binding[1].dwPart = DBPART_VALUE; Binding[1].dwMemOwner = DBMEMOWNER_CLIENTOWNED; Binding[1].eParamIO = DBPARAMIO_NOTPARAM; Binding[1].wType = DBTYPE_STR; Binding[1].cbMaxLen = 255; Binding[2].iOrdinal = 2; Binding[2].obValue = offsetof(ENUMPROVIDERSROW, ParseName); Binding[2].dwPart = DBPART_VALUE; Binding[2].dwMemOwner = DBMEMOWNER_CLIENTOWNED; Binding[2].eParamIO = DBPARAMIO_NOTPARAM; Binding[2].wType = DBTYPE_STR; Binding[2].cbMaxLen = 255; Binding[3].iOrdinal = 3; Binding[3].obValue = offsetof(ENUMPROVIDERSROW, SourceDesc); Binding[3].dwPart = DBPART_VALUE; Binding[3].dwMemOwner = DBMEMOWNER_CLIENTOWNED; Binding[3].eParamIO = DBPARAMIO_NOTPARAM; Binding[3].wType = DBTYPE_STR; Binding[3].cbMaxLen = 255; Binding[4].iOrdinal = 4; Binding[4].obValue = offsetof(ENUMPROVIDERSROW, SourceType); Binding[4].dwPart = DBPART_VALUE; Binding[4].dwMemOwner = DBMEMOWNER_CLIENTOWNED; Binding[4].eParamIO = DBPARAMIO_NOTPARAM; Binding[4].wType = DBTYPE_UI2; Binding[5].iOrdinal = 5; Binding[5].obValue = offsetof(ENUMPROVIDERSROW, IsParent); Binding[5].dwPart = DBPART_VALUE; Binding[5].dwMemOwner = DBMEMOWNER_CLIENTOWNED; Binding[5].eParamIO = DBPARAMIO_NOTPARAM; Binding[5].wType = DBTYPE_BOOL; Binding[6].iOrdinal = 6; Binding[6].obValue = offsetof(ENUMPROVIDERSROW, SourceCLSID); Binding[6].dwPart = DBPART_VALUE; Binding[6].dwMemOwner = DBMEMOWNER_CLIENTOWNED; Binding[6].eParamIO = DBPARAMIO_NOTPARAM; Binding[6].wType = DBTYPE_STR; Binding[6].cbMaxLen = 255; hr = pAccessor->CreateAccessor( DBACCESSOR_ROWDATA, COLS, &Binding[0], 0, &hAccessor, &BindingStatus[0]); if( hr == S_OK ) { hr = pRowset->RestartPosition( DB_NULL_HCHAPTER ); while(true) { hr = pRowset->GetNextRows( DB_NULL_HCHAPTER, 0, ROWS, &Feched, &phRow); if( (hr == S_OK || hr == DB_S_ENDOFROWSET) && Feched ) { SAFEARRAYBOUND MyBound[2]; MyBound[0].cElements = Feched-2; //first item lost MyBound[1].cElements = Feched-2; MyBound[0].lLbound = 0; MyBound[1].lLbound = 0; res->vt = VT_VARIANT | VT_ARRAY; res->parray = SafeArrayCreate(VT_VARIANT,2,MyBound); long MyPosition[2]; VARIANT tmp; VariantInit(&tmp); for(int i=0; i<(int)Feched; i++) { pRowset->GetData( phRow[i], hAccessor, (LPVOID)&Rows);MyPosition[0] = i;MyPosition[1] = 0;tmp.vt =VT_BSTR;tmp.bstrVal = SysAllocString(A2BSTR(Rows.SourceName));SafeArrayPutElement(res->parray,MyPosition,&tmp);MyPosition[1] = 1;SysFreeString(tmp.bstrVal);tmp.bstrVal = SysAllocString(A2BSTR(Rows.ParseName));SafeArrayPutElement(res->parray,MyPosition,&tmp);MyPosition[1] = 2;SysFreeString(tmp.bstrVal);tmp.bstrVal = SysAllocString(A2BSTR(Rows.SourceDesc));SafeArrayPutElement(res->parray,MyPosition,&tmp);MyPosition[1] = 3;SysFreeString(tmp.bstrVal);tmp.vt = VT_I2;tmp.iVal = Rows.SourceType ;SafeArrayPutElement(res->parray,MyPosition,&tmp);MyPosition[1] = 4;tmp.vt = VT_BOOL;tmp.boolVal = Rows.IsParent ;SafeArrayPutElement(res->parray,MyPosition,&tmp);MyPosition[1] = 5;tmp.vt = VT_BSTR;tmp.bstrVal = SysAllocString(A2BSTR(Rows.SourceCLSID));SafeArrayPutElement(res->parray,MyPosition,&tmp);SysFreeString(tmp.bstrVal); } pRowset->ReleaseRows( Feched, phRow, NULL, NULL, NULL); if( hr == DB_S_ENDOFROWSET) break; } else break; } pAccessor->ReleaseAccessor( hAccessor, NULL); } pAccessor->Release(); } pRowset->Release(); } } delete[] phRow; return hr;}
To use it in a VB project is straightforward - add a reference to "AllProvs 1.0 Type Library" and add the code:
Dim x As New ALLPROVSLib.ProvidersPrivate Sub Command1_Click()Dim a As Varianta = x.GetProvidersFor i = 0 To UBound(a, 1) For j = 0 To UBound(a, 2) Debug.Print a(i, j) & " - "; NextDebug.PrintNextEnd Sub
原文网址:http://www.advancode.com/articles.php?page=oledbproviders
- OLEDB Providers Enumeration
- Enumeration
- Enumeration
- enumeration
- Enumeration
- Enumeration
- Enumeration
- Enumeration
- Enumeration
- Enumeration
- Enumeration
- Enumeration
- oledb
- OLEDB
- OLEDB
- OLEDB
- OLEDB
- OLEDB
- DWR 调用远程方法的错误和异常处理
- Java 之代理模式
- 我把爱情煲成汤:一段伤感的小资爱情 楔子(1)
- 网络安全系列连载(3)电子邮件与数字证书
- 漏屋告诉你外语学习的真实方法及误区分析整理(转载)
- OLEDB Providers Enumeration
- 闲扯
- 初探Win2000索引服务的WEB应用
- 网络安全系列连载(4)网站服务器与数字证书
- 当代企业电子商务的市场战略
- 关于电子商务的分类及模式
- 用EditPlus搭建汇编编译环境
- 小菜学设计模式 单一职责原则
- Andorid环境Python编程