Microsoft KB Archive/182831

= HOWTO: Using the ADO OpenSchema Method from Visual C++ =

Article ID: 182831

Article Last Modified on 3/14/2005

-

APPLIES TO


 * Microsoft ActiveX Data Objects 1.5
 * Microsoft ActiveX Data Objects 2.0
 * Microsoft ActiveX Data Objects 2.1
 * Microsoft ActiveX Data Objects 2.5
 * Microsoft ActiveX Data Objects 2.6
 * Microsoft ActiveX Data Objects 2.7
 * Microsoft Data Access Components 2.7

-



This article was previously published under Q182831



SUMMARY
This article demonstrates how to use the ActiveX Data Objects (ADO) OpenSchema method from Visual C++ using the #import feature. OpenSchema is a method of ADO the Connection object that obtains database schema information from the OLEDB provider.



MORE INFORMATION
OpenSchema returns information about the data source, such as information about the tables on the server and the columns in the tables. OpenSchema returns the schema information as a resultset.

OpenSchema has three parameters. The first parameter is an enumerated value specifying the type of the schema required. The second parameter is a variant array. The number of elements and the contents in the array depend on the type of the schema query to be run. You can use this parameter to restrict the number of rows returned in the resultset. However, you cannot limit the number of columns returned by OpenSchema. The third parameter is required only if the first parameter is set to adSchemaProviderSpecific; otherwise, it is not used.

For additional information about Using Stored Procedures with ADO, please see the following article(s) in the Microsoft Knowledge Base:

184968 FILE: Adovcsp.exe Demonstrates Using Stored Procedures with ADO

The following code demonstrates using OpenSchema to get information about the primary key of a table (#IMPORT statement is not shown here): void OpenSchemaForPrimaryKey {

ADODB::_ConnectionPtr Con; ADODB::_RecordsetPtr  Rs1;

CString csTemp; _variant_t varCriteria[3]; LONG lIndex = 0; HRESULT hr = 0; int nIndex;

try {

// Getting primary key information for table "Authors". _bstr_t mydatabase("pubs"); _bstr_t mydbo("dbo"); _bstr_t mytable("authors");

varCriteria[0] = mydatabase; varCriteria[1] = mydbo; varCriteria[2] = mytable;

// Creating a safearray of variants with three elements. VARIANT varData; SAFEARRAY FAR* psa; SAFEARRAYBOUND rgsabound[1]; rgsabound[0].lLbound = 0; rgsabound[0].cElements = 3; psa = SafeArrayCreate(VT_VARIANT, 1, rgsabound);

// Fill the safe array. for( lIndex = 0 ; lIndex < 3 ;lIndex++) {       hr  = SafeArrayPutElement(psa, &lIndex,&varCriteria[lIndex]); }     // Initialize the safearray. varData.vt = VT_VARIANT | VT_ARRAY; V_ARRAY(&varData) = psa;

Con.CreateInstance(__uuidof(ADODB::Connection));

Con->Open(L"DSN=pubs", L"", L"", -1L); Rs1 = Con->OpenSchema(ADODB::adSchemaPrimaryKeys,varData);

int nFieldCount = Rs1->Fields->GetCount; VARIANT varValue;

while (VARIANT_TRUE != Rs1->GetadoEOF) {         csTemp.Empty; // Traversing through the Fields collection to get the values. for(nIndex = 0 ; nIndex < nFieldCount ; nIndex++) {        if(!csTemp.IsEmpty) csTemp += " ; ";

csTemp += Rs1->Fields->GetItem(_variant_t((long)nIndex))->Name; csTemp += " = "; varValue = Rs1->Fields->GetItem(_variant_t((long)nIndex))->Value;

if(varValue.vt == VT_BSTR) csTemp += varValue.bstrVal; else if(varValue.vt == VT_UI4) csTemp.Format("%s %l",csTemp,varValue.lVal);

} // End of For loop. AfxMessageBox(csTemp); Rs1->MoveNext;

} // End of While loop.

} // End of Try block.

catch(_com_error &e)

{      // Exception handling. DumpError(e); }

} // End of function.

The following code demonstrates using the OpenSchema method to retrieve all table names present in the database. The function excludes system tables and views. // Function that gets all table names & excludes System tables and views void OpenSchemaTables {

ADODB::_ConnectionPtr Con; ADODB::_RecordsetPtr  Rs1;

CString csTemp; _variant_t varCriteria[4]; LONG lIndex = 0; HRESULT hr = 0;

try {            // Getting primary key information for table "Authors".

_bstr_t bstrTableType("Table");

varCriteria[0].vt = VT_EMPTY; varCriteria[1].vt = VT_EMPTY; varCriteria[2].vt = VT_EMPTY; varCriteria[3] = bstrTableType;

VARIANT varData; SAFEARRAY FAR* psa; SAFEARRAYBOUND rgsabound[1]; rgsabound[0].lLbound = 0; rgsabound[0].cElements = 4; psa = SafeArrayCreate(VT_VARIANT, 1, rgsabound);

// Fill the safe array. for( lIndex = 0 ; lIndex < 4 ;lIndex++) {               hr  = SafeArrayPutElement(psa, &lIndex,&varCriteria[lIndex]); }            // Initialize variant with safearray. varData.vt = VT_VARIANT | VT_ARRAY; V_ARRAY(&varData) = psa; Con.CreateInstance(__uuidof(ADODB::Connection)); Con->Open(L"DSN=pubs", L"", L"", -1L);

Rs1 = Con->OpenSchema(ADODB::adSchemaTables,varData);

int nFieldCount = Rs1->Fields->GetCount; VARIANT varValue;

csTemp.Empty; while (VARIANT_TRUE != Rs1->GetadoEOF) {               // Traversing through the Fields collection to get the values. if(!csTemp.IsEmpty) csTemp += " ; ";

varValue = Rs1->Fields->GetItem(_variant_t((long)2))->Value; if(varValue.vt == VT_BSTR) csTemp += varValue.bstrVal; else if(varValue.vt == VT_UI4) csTemp.Format("%s %l",csTemp,varValue.lVal);

Rs1->MoveNext; }            OutputDebugString(csTemp); }         catch(_com_error &e) {            // Exception handling. DumpError(e); }

}

// Utility function that gets error information from _com_error and // displays an error message box. void DumpError(_com_error &e) {        _bstr_t bstrSource(e.Source); _bstr_t bstrDescription(e.Description); CString str; str.Format("\tCode = %08lx", e.Error); str += " Msg: ";  str += e.ErrorMessage; str += " Source: "; str += bstrSource; str += " Description: "; str += bstrDescription; AfxMessageBox(str); }

