Categories: MSDN / DotNet / Java / Scripts / Linux / PHP Ask - La ask - La Answer

How do I connect to mdb using Visual C++?

Need help to set up a connection to mdb on Visual C++. I have got it working for VB using Microsoft.Jet.OLEDB.4.0 and ADO stuff. How about for C++?? How do I do it?
Thanks.
[182 byte] By [yhx] at [2007-11-11 10:15:33]
# 1 Re: How do I connect to mdb using Visual C++?
I have experience in one method : ODBC (in VC++6).
If you want do it in a more generic state (dialog based, not SDI/MDI), that is take more work, then follow these steps :

1.Create a dialog based app and then with ClassWizard, add a new class that drived from CRecordset class (It wil be your Database class) (at this time you can specify your .mdb file)

2. Add the following to 'StdAfx.h' : #include <afxdb.h> // MFC ODBC database classes

==> Notes :

=> NOTE : You should test that the end user have the ODBC Driver for your database (such as Microsoft Access Driver)
and if not, you should install that driver for your program working.

=> NOTE : Maximum length of DataSource name must be 32 character, and the name shouldn't be included following characters :
[ ] { } ( ) , ; ? * = ! @ \
=> NOTE : The information about added DataSources in the system, is in the file : C:\windows\ODBC.ini

=> NOTE : A recordset can join two or more tables from the same data source, but not from different data sources.

=> NOTE : m_nParams -> you 'only' need to initialize this variable (not defining or ...)
this is a data member of class CRecordset : UINT CRecordset::m_nParams; // number of RFX params
For initializing : in your Database class constructor (in .cpp) initialize it (Outside of 'Field Map' or
any other subscope). EX : m_nParams = 3;

=> NOTE : The general form of an SQL SELECT statement is :

SELECT [ALL | DISTINCT] column-list FROM table-list
[WHERE search-condition][ORDER BY column-list [ASC | DESC]]

- Your column list should match the column names and types in the same order as they are listed in DoFieldExchange.
- 'DISTINCT' can be used just after 'SELECT' (and just before first column name), and if you used that, you can
use 'ORDER BY' only with the first column name (in column-list), and without any sorting from you, the result
will be in ascending order

=> NOTE : MSDN says :
"ClassWizard doesnt support declaring a recordset class for calling a predefined query"
"You can create a single recordset class to manage calling a predefined query, but you must do some of the work yourself. ClassWizard doesnt support creating a class specifically for this purpose."

=> NOTE : MSDN says : "One way to add the DISTINCT keyword to your recordsets SQL statement is to embed
the keyword in the first RFX function call in DoFieldExchange. For example:

...
RFX_Text(pFX, "DISTINCT CourseID", m_strCourseID);
...

WARNING : Use this technique only with a recordset opened as read-only. "

BUT, it has no effect!

=> NOTE : To override the default SELECT statement, pass a string containing a complete SELECT statement when you call CRecordset::Open. Instead of constructing its own default string, the recordset uses the string you supply. If your replacement statement contains a WHERE clause, dont specify a filter in m_strFilter because you would then have two filter statements. Similarly, if your replacement statement contains an ORDER BY clause, dont specify a sort in m_strSort so that you will not have two sort statements.

BUT, If you have added 'ORDER BY', with filter (m_strFilter) provided, your program runs but you will get an error
and there is no result.

=> Function :

BOOL SQLConfigDataSource(
HWND hwndParent,
WORD fRequest,
LPCSTR lpszDriver,
LPCSTR lpszAttributes
);

Usage :

To Add, Remove, Configure(Modify an existing), a DataSource.
(For more function descriptions see MSDN)

For Using :

1. -include 'odbcinst.h' in the source file that use 'SQLConfigDataSource'
(#include <odbcinst.h> (this is in 'include' folder of VC++))
-(This is needed for 'SQLConfigDataSource' prototype and 'request flags' defenitions.)

2. -Add 'ODBCCP32.LIB' to your project, (this file is in your VC++ setup CD-> VC98\LIB)
([Menu]->[Project]->[Add to project]->[Files...])
-This will appear in your 'FileView' pane.
-(This is needed for 'SQLConfigDataSource' defenition in file : 'ODBCCP32.DLL')

Example :

SQLConfigDataSource(NULL, // No Window handle
ODBC_ADD_DSN, // add new DataSource
"Microsoft Access Driver (*.mdb)", // in this call, it's not effect
"DSN=YourDataSourceName\0"
"DBQ=c:\\YourDatabase.mdb\0" // if your Access Database file is 'YourDatabase.mdb'
// and exists in 'C:' drive
);

=> Connect to a access database : <=

CDatabase db;

db.OpenEx( _T( "DSN=DataSourceName" ) ); // if you don't provide any of the following informations,
// and that is necesssary for openning the database,
// the system will appear a window and get that information
// 1.UserID (UID) 2.Password (PWD) 3.DataSource name (DSN)

db.Close(); // You must close any open recordsets associated with this CDatabase object(db)
// The database object will not be destroyed and you can reuse that after disconnecting from it,
// whether you use it to reconnect to the same data source or to connect to a different data source.

CRecordset* CSectionView::OnGetRecordset() // Example of defining a function to manage the exceptions
{
if ( m_pSet != NULL )
return m_pSet; // Recordset already allocated

m_pSet = new CSectionSet( NULL );
try
{
m_pSet->Open( );
}
catch( CDBException* e )
{
AfxMessageBox( e->m_strError,
MB_ICONEXCLAMATION );
// Delete the incomplete recordset object
delete m_pSet;
m_pSet = NULL;
e->Delete();
}
return m_pSet;
}

=> CDatabase* CRecordset::m_pDatabase => this data member stores the CDatabase object associated with the recordset
if you dont initialize this pointer, the recordset will get its associated database information by calling
GetDefaultConnect() function. You can change this function, it is one of your drived database class function.
For Example : if your drived database class name is : DDBC, then the function defenition will be :

CString DDBC::GetDefaultConnect()
{
return _T("ODBC;DSN=DataSourceName");
}

the 'DataSourceName' is the name of the your datasource (you specified that when you created the database class
whit the ->[ClassWizard->Add Class...->New...].

.: End :. :WAVE:
Mohammad Rast at 2007-11-11 20:59:12 >
# 2 Re: How do I connect to mdb using Visual C++?
Thank you Rast.
yhx at 2007-11-11 21:00:08 >