Solved

C++ and Access

Posted on 2004-08-26
4
404 Views
Last Modified: 2013-11-25
Hello all,

Is there a way to write to an Access 2000 database using straight C++?  I would like to do it without using MFC, just straight console.  Any and all help is greatly appreciated!  Thanks in advance!

Tony
0
Comment
Question by:fattumsdad
  • 2
4 Comments
 
LVL 3

Expert Comment

by:Indrawati
ID: 11909824
Any reason why you don't want to use MFC? Since Access is made by Microsoft, I doubt you can easily manipulate access databases without MFC, unless you know the internal data structure of Access.
0
 
LVL 19

Accepted Solution

by:
drichards earned 500 total points
ID: 11909930
Yes, it's very easy with OLEDB.  You can really go native and use the raw COM calls, but the ATL template OLEDB classes are a lot easier to use.  Here's some code to demonstrate how it works.  Similar to ODBC, this code will work against any database that has an OLEDB driver.  Here's a link to the docs, too:

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vclib/html/vcrefoledbtemplates.asp


Code:
---------------------------------
#include <atldbcli.h>
#include <atldbsch.h>

void PrintRowsetData(ATL::CAccessorRowset<CDynamicAccessor> &rs)
{
    HRESULT hr = rs.MoveFirst( );
    while( SUCCEEDED( hr ) && hr != DB_S_ENDOFROWSET )
    {
        for( size_t i = 1; i <= rs.GetColumnCount( ); i++ )
        {
            DBTYPE type;
            rs.GetColumnType( i, &type );
            printf( "Column %d [%S] is of type %d\n", i, rs.GetColumnName( i ), type );
               
            switch( type )
            {
            case DBTYPE_WSTR:
                printf( "value is %S\n", (WCHAR*)rs.GetValue( i ) );
                break;
            case DBTYPE_STR:
                printf( "value is %s\n", (CHAR*)rs.GetValue( i ) );
            default:
                printf( "value is %d\n", *(long*)rs.GetValue( i ) );
            }
        }
        hr = rs.MoveNext( );
    }
}

void OLEDBTest()
{
    ::CoInitialize(NULL);
    ATL::CDataSource ds;
    // This uses a UDL file for initialization parameters
    if ( ds.OpenFromFileName(OLESTR("F:\\MyDB.udl")) == S_OK )
    // Could also generate prompt for UDL file - same code would work against any OLE DB provider (like SQL Server)
    // if ( ds.OpenWithPromptFileName() == S_OK )
    {
        ATL::CSession session;
        if ( session.Open(ds) == S_OK )
        {
            // LIst the tables in the database
            ATL::CTables tables;
            tables.Open(session, NULL, NULL, NULL, "TABLE");
            char tableName[32];
            tableName[0] = 0;
            while (tables.MoveNext() == S_OK )
            {
                std::cout << "Table: " << tables.m_szName << std::endl;
                // Save first table name
                if ( tableName[0] == 0 ) ::strcpy(tableName, tables.m_szName);
            }

            // Show a table - use dynamic accessor to discover column names
            ATL::CTable<CDynamicAccessor> table;
            table.Open(session, tableName);
            PrintRowsetData(table);
            table.Close();

            std::cout << std::endl << "------------------------" << std::endl << std::endl;

            // Run a command, again with dynamic accessor
            ATL::CCommand<CDynamicAccessor> command;
            char cmdStr[64];
            // Column names hardcoded here (could just select names from table info above)
            ::sprintf(cmdStr, "SELECT Name, Phone FROM %s;", tableName);
            command.Open(session, cmdStr);
            PrintRowsetData(command);
            command.Close();

            session.Close();
        }
        ds.Close();
    }
    ::CoUninitialize();
}
0
 
LVL 19

Expert Comment

by:drichards
ID: 11915915
Just a note about the code as I look at it:  You'll need to create a udl file and change the code to open it rather than "F:\MyDB.udl".  Easiest way is to go into file explorer right pane and right click and do New->Text File and rename the file to <your name>.udl.  Then double-click on the empty udl file and you'll get a configuration dialog.  On the Provider tab, select "Microsoft Jet 4.0 OLE DB Provider".  If you're using Access prior to Acces 2000, use Jet 3.51 provider.

Then on the Connection tab select the Access file and test the connection.  That will get you going.

You'll also want to change the query for the CCommand to something that will work on your database.
0
 
LVL 1

Author Comment

by:fattumsdad
ID: 11916121
drichards,

I appreciate all the help!  Thanks a lot!!

Regards,
Tony
0

Featured Post

Free Tool: Site Down Detector

Helpful to verify reports of your own downtime, or to double check a downed website you are trying to access.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

When writing generic code, using template meta-programming techniques, it is sometimes useful to know if a type is convertible to another type. A good example of when this might be is if you are writing diagnostic instrumentation for code to generat…
Article by: SunnyDark
This article's goal is to present you with an easy to use XML wrapper for C++ and also present some interesting techniques that you might use with MS C++. The reason I built this class is to ease the pain of using XML files with C++, since there is…
The viewer will be introduced to the technique of using vectors in C++. The video will cover how to define a vector, store values in the vector and retrieve data from the values stored in the vector.
This is Part 3 in a 3-part series on Experts Exchange to discuss error handling in VBA code written for Excel. Part 1 of this series discussed basic error handling code using VBA. http://www.experts-exchange.com/videos/1478/Excel-Error-Handlin…

756 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question