Connecting to an Access 2000 .mdb database with visual C++ ADO commands

In summary: Try this: ADODB::_ConnectionPtr _DC; hr = _DC.CreateInstance( __uuidof(ADODB::Connection) ); _DC->Open( _ConnectionString.c(), L"", L"", ADODB::adAsyncConnect ); if( SUCCEEDED( hr ) ) { ADODB::_RecordsetPtr pRS("ADODB.Recordset"); hr = pRS.CreateInstance( __uuidof(ADODB::Recordset) ); hr = pRS->Open( _bstr_t("SELECT * FROM Table"), _DC.GetInterfacePtr(), ADODB::adOpenForwardOnly, ADODB::adLockReadOnly, ADODB::adCmdText ); } if( SUCCEEDED( hr )
  • #1
CFDFEAGURU
783
10
Hello all,

I am trying to connect to an Access database, the Northwind sample database, by following this example,

http://msdn.microsoft.com/en-us/library/cc811599.aspx

I am using a Windows XP OS with Visual C++ 2008 Express for the compiler and IDE. The program is a console application. This example is specified for Access 2007 .accdb file types and doesn't specify if a .mdb file type will cause errors.

Once I get it running correctly I will switch the path name, queries, and table names to my database.

The code compiles correctly, but fails to execute.

Here is the code

Code:
#include <fstream>
#include <cmath>
#include <complex>
#include <iostream>
#include <iomanip>
#include <vector>
#include <limits>
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#include <fcntl.h>
#include <string.h>
#include <ctype.h>
#include <icrsint.h>

using namespace std;

#import <C:\\Program Files\\Common Files\\system\\ado\\msado15.dll> rename( "EOF", "AdoNSEOF")

_bstr_t bstrConnect = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\\Program Files\\Microsoft Office\\Office\\Samples\\Northwind.mdb;";

HRESULT hr;

int main()
{
	::CoInitialize(NULL);
	const char* DAM = "ADO";
	ADODB::_ConnectionPtr pConn("ADODB.Connection");
	hr = pConn->Open(bstrConnect, "admin", "", ADODB::adConnectUnspecified);
	if(SUCCEEDED(hr))
	{
		cout<<DAM<<": Successfully connected to database. Data source name:\n  "
			<<pConn->GetConnectionString()<<endl;

		// Prepare SQL query
		_bstr_t query = "SELECT Customers.[Company], Customers.[First Name] FROM Customers;";
		cout <<DAM<<": SQL query \n  "<<query<<endl;

		// Execute
		ADODB::_RecordsetPtr pRS("ADODB.Recordset");
		hr = pRS->Open(query,
			_variant_t((IDispatch *) pConn, true),
			ADODB::adOpenUnspecified,
			ADODB::adLockUnspecified,
			ADODB::adCmdText);
		if(SUCCEEDED(hr))
		{
			cout<<DAM<<": Retrieve schema info for the given result set: "<< endl;
			ADODB::Fields* pFields = NULL;
			hr = pRS->get_Fields(&pFields);
			if(SUCCEEDED(hr) && pFields && pFields->GetCount() > 0)
			{
				for(long nIndex=0; nIndex < pFields->GetCount(); nIndex++)
				{
					cout << " | "<<_bstr_t(pFields->GetItem(nIndex)->GetName());
				}
				cout << endl;
			}
			else
			{
				cout<<DAM<<": Error: Number of fields in the result is set to zero." << endl;
			}
			cout<<DAM<<": Fetch the actual data: " << endl;
			int rowCount = 0;
			while (!pRS->AdoNSEOF)
			{
				for(long nIndex=0; nIndex < pFields->GetCount(); nIndex++)
				{
					cout<<" | "<<_bstr_t(pFields->GetItem(nIndex)->GetValue());
				}
				cout<< endl;
				pRS->MoveNext();
				rowCount++;
			}
			cout<<DAM<<": Total Row Count:  " << rowCount << endl;
		}
		pRS->Close();
		pConn->Close();
		cout<<DAM<<": Cleanup Done" << endl;
	}
	else
	{
		cout<<DAM<<" : Unable to connect to data source: "<<bstrConnect<<endl;
	}
	::CoUninitialize();
	return 0;
}

The error is with the hr statement. It has an unhandled exception.

I don't know what is causing this.

Any help would be appreciated.

Thanks
Matt
 
Technology news on Phys.org
  • #2
What's the exception that is thrown? That will give you a clue as to what the problem is.

Do you know how to use the Visual Studio debugger? The value stored in hr after Open returns will give you an idea as to what's the problem.
 
  • #3
The exception that is thrown is;

Unhandled exception at memory location ...

The same error you would get if tried to access information outside the boundaries of an array.

Yes, I know how to use the debugger. The value in the Open statement says IUknown in the location for the machine name. I have tried numerous names other than "admin" and still get the same error.

Thanks
Matt
 
  • #4
Are you sure that:

ADODB::_ConnectionPtr pConn("ADODB.Connection");

Actually creates an ADODB::Connection object?

I have just checked some of my code and it creates a connection like this:

ADODB::_ConnectionPtr _DC;
hr = _DC.CreateInstance( __uuidof(ADODB::Connection) );
_DC->Open( _ConnectionString.c(), L"", L"", ADODB::adAsyncConnect );

That is for connecting async to SQL server with the username and password in the connection string itself.
 
  • #5
silverfrost:

Thanks. I had added your code but now I have a new error.

The error is;

:error C2660: 'ADODB::Connection15::Open' : function does not take 5 arguments

So I am trying to pass too many arguments.

Here is the code block where that occurs.

Code:
ADODB::_RecordsetPtr pRS("ADODB.Recordset");
		hr = _DC->Open(query,
			_variant_t((IDispatch *) _DC, true),
			ADODB::adOpenUnspecified,
			ADODB::adLockUnspecified,
			ADODB::adCmdText);

The adCmdText is the line that the debugger points to.

If I change the _DC->Open line to _DC->Open(query,"admin","",ADODB::adOpenUnspecified"

The code compiles but, I get this error

Unhandled exception at 0x7c812afb in Database Connection 2.exe: Microsoft C++ exception: _com_error at memory location 0x0012fbcc..

The debugger directs me to this snippet of code located in the msado15.tli file.

Code:
inline HRESULT Connection15::Open ( _bstr_t ConnectionString, _bstr_t UserID, _bstr_t Password, long Options ) {
    HRESULT _hr = raw_Open(ConnectionString, UserID, Password, Options);
    if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this));
    return _hr;
}

Any help would be greatly appreciated.

Thanks
Matt
 
Last edited:
  • #6
I think you are confusing the Recordset open with the Connection open. The connection open opens the connection and once it is open you can open a recordset from it. Your original code was about right, you just didn't create an object.
 

Related to Connecting to an Access 2000 .mdb database with visual C++ ADO commands

1. How do I connect to an Access 2000 .mdb database using Visual C++ ADO commands?

To connect to an Access 2000 .mdb database with Visual C++ ADO commands, you will need to include the Microsoft ActiveX Data Objects (ADO) library in your project. Then, you can use the ADO Connection object to establish a connection to the database by providing the database file path and any necessary authentication credentials.

2. What are the benefits of using ADO commands to connect to an Access 2000 .mdb database?

Using ADO commands to connect to an Access 2000 .mdb database allows for a more streamlined and efficient way to access and manipulate data in the database. ADO provides a consistent set of methods and properties for working with different types of databases, making it easier to write code that can be used for multiple databases.

3. Can I use ADO commands to retrieve data from an Access 2000 .mdb database?

Yes, ADO commands can be used to retrieve data from an Access 2000 .mdb database. You can use the ADO Recordset object to execute SQL queries and retrieve data from the database. The retrieved data can then be used in your C++ code for further processing.

4. Do I need to have Microsoft Access installed in order to connect to an Access 2000 .mdb database with ADO commands?

No, you do not need to have Microsoft Access installed in order to connect to an Access 2000 .mdb database with ADO commands. ADO uses the Microsoft Jet Database Engine to communicate with the database, so you will only need to have the appropriate driver for the Access 2000 .mdb file installed on your computer.

5. Are there any potential issues I should be aware of when using ADO commands to connect to an Access 2000 .mdb database?

One potential issue to be aware of is that ADO commands may not be compatible with newer versions of Access databases (such as .accdb files). Additionally, ADO commands may not work if the database is password-protected or if certain security settings are enabled. It is important to thoroughly test your code and handle any potential errors that may arise.

Back
Top