Obtain the structure information of a heterogeneous database using VC ++

Source: Internet
Author: User
Tags driver manager

Obtain the structure information of a heterogeneous database using VC ++

Abstract: Based on the introduction of ODBC technology, This paper combines MFC and ODBC APIs to create two custom classes to obtain the structure information of any database with different configuration types.

Keywords: ODBC, MFC, heterogeneous database, record set

I. Question proposal

With the rapid development of database technology in various application fields, the market has launched a variety of database systems. In order to make full use of resources and achieve information sharing, in this way, users can access Heterogeneous Databases transparently (including data query, update, and exchange). The author developed a communication platform for heterogeneous databases. In the development of the platform, obtaining structure information of various heterogeneous databases is a prerequisite for data access. The author uses VC ++ 5.0 as the development language and uses ODBC to implement this key technology.

Ii. ODBC technology introduction

ODBC technology refers to open database connection technology, which allows applications to exchange data with data sources without worrying about the DBMS from which the data source comes. Traditional ODBC programming is implemented by calling ODBC APIs in advanced languages (such as C. The application requires the driver manager and each driver to allocate information storage space for the ODBC environment, each connection, and each SQL statement, and return a handle pointing to each storage area for calling.

The ODBC interface defines three types of handles:

Environment handle: identifies memory storage for the entire process, including valid connection handle and active connection handle. ODBC defines the environment handle as a henv variable. The application uses a single environment handle, which must be requested before connecting to the data source.

Connection handle: identifies memory storage for specific connection information. ODBC defines the connection handle as the hdbc type. The application must request a connection handle before connecting to the data source. Each connection handle is related to the Environment handle. However, the environment handle can have multiple connection handles related to it.

Statement handle: identifies memory storage for SQL statement information. ODBC defines the statement handle as a hstmt variable. The application must request the statement handle before submitting an SQL request. Each statement handle is related to a connection handle. However, each connection handle can have multiple statement handles related to it.

The following uses the C language as an example to illustrate the general process of traditional ODBC programming.

1. Environment application. Allocate the environment handle henv; sqlallocenv (& henv); Description: Allocate an environment handle and support one or more data source connections.

2. Connection Request, allocate the connection handle hdbc; sqlallocconnect (henv, & hdbc); Description: A connection handle corresponds to a data source and can have multiple connection handles.

3. Connect to the data source and connect to the data source sqldriverconnect (hdbc,...) using the connection handle. Description: obtain registration information in the dialog box and connect to the data source.

4. Statement application and statement handle allocation

Sqlallocstmt (hdbc, & hstmt); Description: Obtain the statement handle to execute the SQL statement.

5. Execute SQL statements

Sqlexecdirect (hstmt, sqlstatement,...); Description: Execute an SQL statement using the statement handle.

6. Release all resources

Sqlfreestemt (hsf-st,...); // release statement handle

Sqldisconnect (hdbc); // disconnect

Sqlfreeconnect (hdbc); // release the current database connection handle

Sqlfreeenv (henv); // release the environment handle

Iii. Obtain structure information of a heterogeneous database using VC ++ and ODBC

The traditional ODBC programming process is complicated, and various parameters are difficult to understand, and it is difficult to directly obtain the returned data. The VC ++ 5.0 MFC class library encapsulates ODBC APIs, which simplifies ODBC programming (especially database record set operations ), however, it is still difficult to obtain the structure information of a heterogeneous database simply using the MFC class. Therefore, it is necessary to combine the MFC and traditional odbc api programming. The author used ODBC interface functions to overload some member functions of the crecordset class in MFC and create the ctable and ccolumns classes. Using these two newly created classes, you can easily obtain the structure information of a heterogeneous database. The following is the definition of the ctable and ccolumns classes:

Class ctable: Public crecordset {

Virtual cstring getdefaconnect connect () {return "";}

Virtual cstring getdefasql SQL () {return "";}

Public:

Ctable (cdatabase * pdatabase );

Bool open (maid = NULL, maid );

Cstring m_strtablequalifier;

Cstring m_strtableowner;

Cstring m_strtablename;

Cstring m_strtabletype;

Cstring m_strremarks;

Virtual void dofieldexchange (cfieldexchange *);

};

Class ccolumns: Public crecordset {

Virtual cstring getdefaconnect connect () {return "";}

Virtual cstring getdefasql SQL () {return "";}

Public:

Ccolumns (cdatabase * pdatabase );

Bool open (thinkstr psztablequalifier = NULL, thinkstr psztableowner = NULL, thinkstr psztablename = NULL, thinkstr pszcolumnname = NULL, uint nopentype = forwardonly );

Cstring m_strtablequalifier;

Cstring m_strtableowner;

Cstring m_strtablename;

Cstring m_strcolumnname;

Int m_ndatatype;

Cstring m_strtypename;

Long m_nprecision;

Long m_nlength;

Int m_nscale;

Int m_nradix;

Int m_fnullable;

Cstring m_strremarks;

Virtual void dofieldexchange (cfieldexchange *);

};

Bool ccolumns: open (maid, maid, maid ){

Retcode nretcode;

Uword bfunctionexists; // checks whether sqlcolumns functions are supported.

Afx_ SQL _sync (: sqlgetfunctions (m_pdatabase-> m_hdbc, SQL _api_sqlcolumns, & bfunctionexists); If (! Check (nretcode) |! Bfunctionexists ){

If (! Bfunctionexists)

Trace (_ T ("sqlcolumns not supported "));

Return false;

}

// Set the buffer status and allocate the statement handle

Setstate (nopentype, null, readonly );

If (! Allochstmt ())

Return false;

Try {

Onsetoptions (m_hstmt );

Allocstatusarrays ();

// Call the sqlcolumns function of ODBC

Partition (: sqlcolumns (m_hstmt, (uchar far *) partition, SQL _cnt, (uchar far *) psztableowner, SQL _cnt, (uchar far *) psztablename, SQL _nt, (uchar far *) pszcolumnname, SQL _cnt ));

If (! Check (nretcode ))

Throwdbexception (nretcode, m_hstmt );

// Allocate memory and enter information

Allocandcachefieldinfo ();

Allocrowset ();

Movenext ();

M_bbof = m_beof;

}/

/Capture exception information

Catch_all (e ){

Close ();

Throw_last ();

} End_catch_all return true ;}

// Obtain Record set information

Void ccolumns: dofieldexchange (cfieldexchange * pfx ){

Pfx-> setfieldtype (cfieldexchange: outputcolumn );

Rfx_text (pfx, _ T ("table_qualifier"), m_strtablequalifier );

Rfx_text (pfx, _ T ("table_owner"), m_strtableowner );

Rfx_text (pfx, _ T ("table_name"), m_strtablename );

Rfx_text (pfx, _ T ("column_name"), m_strcolumnname );

Rfx_int (pfx, _ T ("data_type"), m_ndatatype );

Rfx_text (pfx, _ T ("type_name"), m_strtypename );

Rfx_long (pfx, _ T ("precision"), m_nprecision );

Rfx_long (pfx, _ T ("length"), m_nlength );

Rfx_int (pfx, _ T ("scale"), m_nscale );

Rfx_int (pfx, _ T ("Radix"), m_nradix );

Rfx_int (pfx, _ T ("nullable"), m_fnullable );

Rfx_text (pfx, _ T ("Remarks"), m_strremarks );

}

Ccolumns: ccolumns (cdatabase * pdatabase): crecordset (pdatabase ){

M_strtablequalifier = _ T ("");

M_strtableowner = _ T ("");

M_strtablename = _ T ("");

M_strcolumnname = _ T ("");

M_ndatatype = 0;

M_strtypename = _ T ("");

M_nprecision = 0;

M_nlength = 0;

M_nscale = 0;

M_nradix = 0;

M_fnullable = 0;

M_strremarks = _ T ("");

M_nfields = 12;

}

Ctable: ctable (cdatabase * pdatabase): crecordset (pdatabase ){

M_strtablequalifier = _ T ("");

M_strtableowner = _ T ("");

M_strtablename = _ T ("");

M_strtabletype = _ T ("");

M_strremarks = _ T ("");

M_nfields = 5;

}

Bool ctable: open (maid, maid ){

Retcode nretcode;

Uword bfunctionexists;

// Check whether the sqltables function is supported

Afx_ SQL _sync (: sqlgetfunctions (m_pdatabase-> m_hdbc, SQL _api_sqltables, & bfunctionexists ));

If (! Check (nretcode) |! Bfunctionexists ){

If (! Bfunctionexists) trace (_ T ("sqltables not supported "));

Return false;

}

// Set the buffer status and allocate the statement handle

Setstate (nopentype, null, readonly );

If (! Allochstmt () return false;

Try {

Onsetoptions (m_hstmt );

Allocstatusarrays ();

// Call the sqltables function of ODBC

Callback (: sqltables (m_hstmt, (uchar far *) tables, SQL _cnt, (uchar far *) psztableowner, SQL _nt, (uchar far *) psztablename, SQL _nt, (uchar far *) psztabletype, SQL _cnt ));

If (! Check (nretcode ))

Throwdbexception (nretcode, m_hstmt );

// Allocate memory and enter information

Allocandcachefieldinfo ();

Allocrowset ();

Movenext ();

M_bbof = m_beof;

}

// Capture exception information

Catch_all (e ){

Close ();

Throw_last ();

} End_catch_all return true;

}

Void ctable: dofieldexchange (cfieldexchange * pfx ){

Pfx-> setfieldtype (cfieldexchange: outputcolumn );

Rfx_text (pfx, _ T ("table_qualifier"), m_strtablequalifier); rfx_text (pfx, _ T ("table_owner"), m_strtableowner );

Rfx_text (pfx, _ T ("table_name"), m_strtablename );

Rfx_text (pfx, _ T ("table_type"), m_strtabletype );

Rfx_text (pfx, _ T ("Remarks"), m_strremarks );

}

The preceding two classes overload the open and dofieldexchange functions of crecordset. The application can create a ctable or ccolumns class as needed, and call the open member function to create the corresponding table structure and field structure record set. Next, we can use the following functions to traverse the structure information of a heterogeneous database.

Void crecordset: movefirst (); // move to the first record

Void crecordset: movelast (); // move to the last record

Void crecordset: moveprev (); // move to the previous record

Void crecordset: movenext (); // move to the next record

Bool crecordset: isbof (); // determines whether it has reached the first record

Bool crecordset: iseof (); // determines whether the last record is reached

Iv. Conclusion

With the custom ctable and ccolumns classes, the application can obtain the structure information of any heterogeneous database. You can conveniently perform operations on unknown databases based on the obtained information. If you combine the ctable and ccolumns classes with document classes and visual classes, you can display the structure information in a certain way in the window. Using the above technology, the author successfully obtained the structure information of various heterogeneous database databases on the communication platform.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.