class ref name: dbconnection_o
category-group: sql
layer: 2
header file: z_dbconnect.h
libraries: libz00.lib libz01.lib libz02.lib

synopsis.
the dbconnection_o class is the ground-level entry point into the database access system of thet Z Directory. Many higher-layer objects use this object. The name is somewhat of a misnomer, for through this object you can do most simple SQL statement execution: SELECT statements, creating tables, inserting rows, etc.

This object is considered quite low-level in the Z Directory. It is easy to use, and easy to grasp conceptually: with one dbconnection_o object instance, you open a connection to a 'back-end' database, form an SQL statement (stuffed into a string object), and execute the statement. Note that there are more powerful objects available - such as the orthodox_o class - that let you easily define a schema for an object, which you can then save to a database (via store_save()) and subsequently retrieve (via store_fetch()).

You can have multiple connections to different databases with this object. Many higher-level Z Directory components are built on top of this "primitive" object.

description.
The dbconnection object acts as an interface that can forward the user requests to different kinds of programmatic mechanisms that access a database. Currently there are 2 mechanisms: ADO and ODBC. The dbconnection_o class is predicated on the ability to open multiple connections to a [back-end] database, each connection having its own cursor and SQL query - statement.

The object's copy constructor is useful in setting up a new query. The parameters for connecting to a database (name, account, password) are copied to the new object, which then has all the required information for opening up its own connection to the database. Each new object instance then can call open() and proceed with executing an SQL statement.

One important concept in understanding how to use this object is the setting of flags that define an SQL "query context". The object was built with the goal of it automatically "doing the right thing", but sometimes the application needs to guide it. Specifically, when a an SQL SELECT query is done, there is a cursor that remains open after the call to the member function sql_exec(). When the object executes a SELECT statement, the number of resultant rows is returned as an output variable for this call. Sometimes this is the desired value and there is no need for subsequent calls based on the query. That is, something like "SELECT count(*) FROM mytable" will yield the desired answer, and the query can be closed. A call to dbconnection_o::sql_close() will close up the query, allowing the object to be reused for another SQL statement. Other times you want the query context to remain open; subsequent calls such as dbconnection_o::sql_fetch() and dbconnection_o::sql_result_value() will return data based on the current open query. Other SQL statements such as INSERT or UPDATE are atomic - there are no subsequent calls applicable for them. The default action is to do a sql_close() after executing the statement. Thus, the application needs to inform the object if the query context is to remain open. It does so by passing a flag object (flag_o) with appropriate flags set:

count_t ncols, nrows;
dbconnection_o dbx;
flag_o f;
f.set (zFlag_DBC_ExecFetch);
f.set (zFlag_DBC_ExecFirstFetch);
dbx.sql_execute("SELECT id FROM country WHERE code = 'us'", nrows, f);
Here, we inform the dbconnection object ('dbx') that a SELECT (eg, a fetch) is going to be performed, and that it is the first time this select statement is to be invoked. After the call to sql_execute() the flag 'zFlag_DBC_ExecFirstFetch' will be turned off. These flags will prevent the object from automatically calling sql_close(). Also, it will make the object close any prior open query contexts before executing the current SQL statement.

If a flag object is passed to sql_execute() with a zero value (all bits off), the query will be closed automatically after the SQL statement is performed. This is the desired action for INSERT and UPDATE statements. Also, then the object goes out of scope, the destructor will automatically close any open query contexts, as well as closing any open channels to the database. These are equivalent to performing sql_close() followed by close().

DB connection flag values.

keyword description
zFlag_DBC_ChannelOpen tells if the object has a valid, functioning connection to the database ("open()" succeeded). This is read-only.
zFlag_DBC_QueryOpen tells if the object has a currently open cursor to an SQL query. This is relevant (and possibly set) only for SQL SELECT statements. It is read-only.
zFlag_DBC_ForceReopen if set, this will close any existing query when doing an "open()"; else, "open()" will simply return. it is not recommended to set this flag.
zFlag_DBC_ExecAutoClose if set (the default), the SQL query will be closed when "sql_execute()" completes. It is not recommended to turn off this flag. in almost all cases, the SQL query done in "sql_execute()" is "atomic" - that is, there is no need to keep the query "alive", as it has fully completed. This is always the case for SQL statements such as CREATE TABLE, UPDATE, DELETE, and SELECT count(*).
zFlag_DBC_ExecWOutput this is a flag parameter value for "sql_execute()", and indicates that the SQL statement to execute has result values. This flag is applicable only for ADO, as it effects certain ADO values. It should not be used for SELECT statements where the results are to be repeatedly fetched after the "sql_execute()" completes.
zFlag_DBC_ExecFetch this should be used as a flag value for "sql_execute()" when a SELECT statement is to be run, and the results are to be repeatedly fetched after the "sql_execute()" (an alternative to having to provide these flags is to call "sql_fetch()", which requires no flag setting).
zFlag_DBC_IsSecret this flag is activated by calling member functdion set_secret(). Once set, the flag cannot be unset, not even by resetting the object. It restricts access to information about the object: the user account and password cannot be obtained by calling the member functions account() or password().
zFlag_DBC_IsTopSecret this flag is activated by calling member functdion set_topsecret(). Once set, the flag cannot be unset, not even by resetting the object. It restricts obtaining almost all information about the object, including the database, database server, user account and password.
zFlag_DBC_VendorWasFound this flag is not a configuration parameter. It is set internally and cannot be modified by the application. If set, it indicates that the manufacturer ("vendor") name has been obtained from the underlying database system. This typically happens when the database is first opened. Once set, the vendor name cannot be changed (done via member function call set_vendor()) unless the object's connection channel is closed.
zFlag_DBC_UsesBrackets this flag is not a configuration parameter. It is determined by setting the vendor, and if set, indicates that column names could (should?) be wrapped with square brackets during SQL statement construction. . This flag should not be set by the application.
zFlag_DBC_IsStrictTypes this flag is not a configuration parameter. It is an internal flag that is determined when setting the DBMS vendor. . This flag should not be set by the application.

member functions (primary)

dbconnection_o()
SIGNATURE: dbconnection_o ()
SYNOPSIS:
creates a a new dbconnection object. No variables are set. The connection method will be set to the default type for the environment (ADO on Microsoft, ODBC on all others).
 

dbconnection_o(dbconnection_o)
SIGNATURE: dbconnection_o (const dbconnection_o &that)
SYNOPSIS:
copy constructor: creates a a new dbconnection object. All info and state vars are simply copied, except "is-open". The copied-to dbconnection object, when a copy occurs, never inherits the RHS "is-open" state (from 'that'). the result will be that this object starts with no connection.
 

operator = (dbconnection_o)
SIGNATURE: const dbconnection_o &operator = (const dbconnection_o &that)
SYNOPSIS: copies the RHS object ('that'). The copy operation is exactly the same as with the copy constructor (which see).
 

destructor
SIGNATURE: ~dbconnection_o ()
SYNOPSIS: virtual destructor. The instance, with all its settings, is wiped out. Any open connections will be closed.
 

dbconnection_o(<args>)
SIGNATURE: dbconnection_o (const string_o &s)
SYNOPSIS:
create a new dbconnection object. The access method is represented by 's', which must be either the literal text "ODBC" or "ADO".
If the string parameter "s" contains anything else, the access method will become undefined (which means all subsequent member function calls will fail, except for set_access_method()).
PARAMETERS

  • s - a string object containing a keyword for the access type employed. Its value must be either "ODBC" or "ADO" (exactly). Any other text strings will result in failure to define the access method (the equivalent of using the default constructor).
  •  

    dbconnection_o(<args>)
    SIGNATURE: dbconnection_o (zstyle_DBAccess x)
    SYNOPSIS: create a new dbconnection object. A local enumerated type, 'zstyle_DBAccess', is used as the parameter to this constructor.
    PARAMETERS

  • x - a zstyle_DBAccess enumerated value. It should be set to one of zstyle_DBax_ODBC or zstyle_DBax_ADO.
  •  

    flag_isset()
    SIGNATURE: boolean flag_isset (int x, int *pi = NULL) const
    PARAMETERS

    • x: a value representing a valid flag value for this class. these include:
      zFlag_DBC_ForceReopen:
      zFlag_DBC_ExecAutoClose:
      zFlag_DBC_ChannelOpen:
      zFlag_DBC_QueryOpen:
    • pi: erorr [output] indicator variable. values:
      0: success
      zErr_Param_BadVal: 'x' is not a valid value
    RETURNS:
    TRUE: the flag is set
    FALSE: the flag is set, or the value in 'x' is not a valid flag value
     

    is_open()
    SIGNATURE: boolean is_open () const
    SYNOPSIS:
    An informational member function: it returns TRUE if a connection has been made to a [back-end] database, and the connection is good (valid; stable).
    RETURNS:
    TRUE: there is an open channel to a database
    FALSE: no connection has been made
     

    access_method()
    SIGNATURE: zstyle_DBAccess access_method () const
    SYNOPSIS:
    returns an enumerated type that describes what kind of database access method is used (or to be used) by the current object.
    RETURNS:
    zstyle_DBAx_ODBC: the object is configured for an ODBC connection
    zstyle_DBAx_ADO: the object is configured for an ADO connection
    zstyle_DBAx_None: the object is not set up for any type of connection
    zstyle_DBAx_Undefined: the object is not set up for any type of connection. this differs from "zstyle_DBAx_None" in that, if set to this, an error occured, whereas "zstyle_DBAx_None" can be set by the client-user (which would wipe out any existing channels via valid connection methods).
     

    vendor()
    SIGNATURE: string_o vendor (int *pi = NULL) const
    SYNOPSIS: returns the vendor name - that is, the database manufacturer's [common] name (eg, "mySQL", "SQL Server", informix", etc).
    PARAMETERS

  • pi: [output] error indicator variable. values:
    0: successful lookup
    zErr_AccessDenied: this information is restricted
    zErr_ThisCall_NotImpl: funcion is not available
  • DESCRIPTION:
    as of 2013, this function has not been implemented - a non-zero error code is indicative of that. This function as of this writing is a placeholder.
     

    server()
    SIGNATURE: string_o server (int *pi = NULL) const
    SYNOPSIS: returns the database server name. The object must not be in "top secret" mode.
    PARAMETERS

  • pi: [output] error indicator variable. values:
    0: successful lookup.
    zErr_AccessDenied: this information is restricted. the object is in "top secret" mode.
    zErr_NotConfigured: value is not set (warning only)
  •  

    name()
    SIGNATURE: string_o name (int *pi = NULL) const
    SYNOPSIS: returns the database name. The object must not be in "top secret" mode.
    PARAMETERS

  • pi: [output] error indicator variable. values:
    0: successful lookup.
    zErr_AccessDenied: this information is restricted. the object is in "top secret" mode.
    zErr_NotConfigured: value is not set (warning only)
  •  

    account()
    SIGNATURE: string_o account (int *pi = NULL) const
    SYNOPSIS: returns the database name. The object must not be in "top secret" mode.
    PARAMETERS

  • pi: [output] error indicator variable. values:
    0: successful lookup.
    zErr_AccessDenied: this information is restricted. the object is in "secret" or "top secret" mode.
    zErr_NotConfigured: value is not set (warning only)
  •  

    password()
    SIGNATURE: string_o password (int *pi = NULL) const
    SYNOPSIS: returns the database name. The object must not be in "top secret" mode.
    PARAMETERS

  • pi: [output] error indicator variable. values:
    0: successful lookup.
    zErr_AccessDenied: this information is restricted. the object is in "secret" or "top secret" mode.
    zErr_NotConfigured: value is not set (warning only)
  •  

    last_op()
    SIGNATURE: zOp_DBConn last_op () const
    SYNOPSIS: returns the last recorded operation the object performed.
     

    last_error()
    SIGNATURE: int last_error () const
    SYNOPSIS: returns the last recorded error the object encountered
    TRAITS: you shouldn't use this, the results are unreliable.
     

    error_mess()
    SIGNATURE: string_o error_mess () const
    SYNOPSIS: returns the last recorded error's message string (if any)
    TRAITS: an inline function.
     

    db_null()
    SIGNATURE: static string_o db_null (int *pi = NULL)
    SYNOPSIS:
    This function returns the string used for setting a string when a database NULL value is encountered during a SELECT (eg, a lookup). The value to use by default is the text found in the macro , and can be modified via the static function set_nullvalue().
    PARAMETERS

  • pi: erorr [output] indicator variable. values: 0: successful
  • RETURNS: the text to use for NULL values, as a string object
     

    get()
    SIGNATURE: int get (int attrib, void *vp, int *pi = NULL)
    SYNOPSIS:
    gets the value of given connection attribute. The value to set to is given by the 2nd parameter, "vp". currently only zdb_Connection_Timeout is implemented.
    PARAMETERS

    • attrib: code-label for the database attribute to set. currently, the only value allowed is zdb_Connection_Timeout.
    • vp: pointer to the simple type containing the value. for zdb_Connection_Timeout, this would be type long int:
      dbconnection_o dbc;
      int ie;
      long int jval;
      dbc.get (zdb_Connection_Timeout, &jval, &ie);
      
    • pi: erorr [output] indicator variable. values: 0: successful
      1: unknown - illegal attribute code
      2: COM/ODBC error occured
    TRAITS:
    this function will probably be overhauled. The name ("get") is not suitable to Z Directory standards, and does not convey much meaning; the use of a "void" pointer is also unacceptable. If you use this, the code will almost certainly break at some future release.
     

    set_true_dbname()
    SIGNATURE: int set_true_dbname (const string_o &new_nam, int *pi)
    SYNOPSIS:
    this function is for ODBC. Some ODBC implementations make a connection to the database server (using the DSN name in the place for the database name in "dbconnection_o::open()" but fail to actually 'open' the database. By calling this function prior to doing the open(), this will basically do a "USE [new_nam]" SQL command, so that the correct database is opened. This function was added as a workaround to this problem.
     

    set_access_method()
    SIGNATURE: int set_access_method (zstyle_DBAccess new_meth, int *pi)
    SYNOPSIS:
    sets the access method (ADO, ODBC) to a database. Note that the 2nd parameter ("pi") is mandatory. If this call results in a change of method, any open channels via the old method are closed and all associated descriptors and handles are de-allocated. You may use zstyle_DBAx_None to set the object to have no access method.
    PARAMETERS

  • new_meth: an enumerated value indicating what access method (technique; implementation) to use. Legal values are:
    zstyle_DBAx_ODBC: sets connection and access to a database to the "ODBC" method
    zstyle_DBAx_ADO: sets connection and access to a database to the "ADO" method. Note, if the platform does not support ADO, the error flag will be set to 2 but this member function will not return error (however, any subsequent database operations will probably fail).
    zstyle_DBAx_None: unsets any active connections and sets the object to a "no-implementations" state.
  •  

    set_vendor()
    SIGNATURE: int set_vendor (const string_o &s, int *pi = NULL)
    SYNOPSIS:
    sets the object's database vendor name. if the database is open, and the vendor info can be obtained from the underlying database system, this call will fail to set the vendor name.
    PARAMETERS

    • s: a string containing the database vendor name.
    • pi: error [output] indicator variable. values: 0: no errors; vendor name was set zErr_CannotModify: vendor name is immutable
    DESCRIPTION:
    as of this writing (2013), the vendor name is not obtained automatically. This means that the zFlag_DBC_VendorWasFound flag is not [currently] set, which allows you to set the vendor name. Otherwise, the database connection needs to be closed (meaning you can reconfigure the object) if you want to change-set the vendor name.
     

    set_topsecret()
    SIGNATURE: int set_topsecret ()
    SYNOPSIS:
    sets a flag which restricts getting information from the object: server name, database name, account and [particularly] password are blocked after this call is done. This call is a one-way street: it cannot be undone.
     

    set_secret()
    SIGNATURE: int set_secret ()
    SYNOPSIS:
    sets a flag which restricts getting information from the object: account and [particularly] password are blocked after this call is done. This call is a one-way street: it cannot be undone.
     

    set_flag()
    SIGNATURE: int set_flag (int x, boolean ison = TRUE)
    SYNOPSIS:
    sets a flag which is allowed to be modified by the application. the allowed flags are zFlag_DBC_ForceReopen and zFlag_DBC_ExecAutoClose.
    PARAMETERS

    • x: a value representing a valid flag value for this class.
    • ison: if TRUE (the default), the flag is set. If FALSE, the flag is cleared.
     

    clear_flag()
    SIGNATURE: int clear_flag (int x)
    SYNOPSIS: clears a flag which is allowed to be modified (see set_flag()).
     

    set()
    SIGNATURE: int set (int attrib, void *vp, int *pi = NULL)
    SYNOPSIS: sets a back-end database paramteter. see "get()" for usage and examples.
     

    set_nullvalue()
    SIGNATURE: int set_nullvalue (const string_o &s, int *pi = NULL)
    SYNOPSIS:
    if a field from a database record is NULL (eg, its value has not been set), something needs to be compied to the string containing the database value. This string would otherwise be uninitialized, hence, containing garbage.
    PARAMETERS

    • s: a string object, containing the string value to be used when a NULL field is encountered in a database lookup. The string can be anything, including an empty string (""), but if it is a simple word (eg no punctuation), 'pi' will be set to zErr_Param_BadFormat to indicate that the string has a dangerous value.
    • pi: error [output] indicator variable. values: 0: no errors; item is set
      zErr_Param_BadFormat: passed-in string is simple "word-type" text (eg, "cow", "GotNull").
      zErr_NoCore: memory exhausted
    DESCRIPTION:
    this function sets a string whose contents is to be used as the value when a NULL is encountered in a relational database field. This static [eg, no object instance is to be used when calling it] function can be called at any time. All subsequent database dbconnection_o lookups where the field value is NULL will be set to this string. This is done inside the object member function dbconnection_o::sql_result_value(). In particular, this is done from dbbi_o::get(), which is called from orthodox_o::store_nfetch() and orthodox_o::store_fetch().
    It is advisable to use a set of [ASCII] characters that would is unlikely to appear in any conventional block of text, such as, say "[[-@@?NuLL**?@@,]]". The default value for this is "![NULL]!" (without the quotes). The string is a compromise between readability-recognizability and being able to use it in a regular expression search:
      #include "z_regex.h"
      void foobar()
      {
        int ie, idx;
        regex_o R;
        R.set_pattern("!\\[NULL\\]!");
        string_o match, sval;
        // use 'sval' in a dbconnection_o lookup..
        idx = R.search (sval, match, &ie);
      }
    

    The converse to this function is db_null(), which returns a string object [copy] of the "null value string".
    RETURNS:
    0: successfully set
    -1: error occurred (see detail value in 'pi')
    TRAITS: this is a static function
     

    open()
    SIGNATURE: int open (int *pi = NULL)
    SYNOPSIS:
    this is basically the samem as the other open() member function - the one with a very long parameter list, and it is a tiny wrapper around it. It uses the object's internally-saved values for doing the connect.
     

    open()
    SIGNATURE: int open (const string_o &server_name, const string_o &db_name, const string_o &user_name, const string_o &passwd, int *pi = NULL)
    SYNOPSIS: opens a connection to database. The access method must be correctly defined in order for this operation to succeed.
    DESCRIPTION:
    This call opens a connection to a databse. If the access method (for the current object) is ODBC, the 2nd parameter, "db_name" should have the ODBC connection name instead of the name of the database to reference (which database an ODBC DSN-adaptor accesses is determined by the adapter). All subsequent calls to sql_execute() will apply to the database referenced by db_name in this call, in most cases. That is, for some databases (Oracle), there is no concept of a specific database. For ODBC, which database to access is defined within the ODBC connection. In all cases, a valid user name and password must be provided.
    In the ADO case, a "connection string" is used with these default [, immutable] values:
    Provider=SQLOLEDB.1
    Persist Security Info=False
    Use Procedure for Prepare=1
    Auto Translate=True
    Packet Size=4096
    Use Encryption for Data=False
    Tag with column collation when possible=False
    TRAITS: the error processing is lacking.
     

    close()
    SIGNATURE: int close (int *pi = NULL)
    SYNOPSIS: closes any open connection.
    RETURNS:
    0: connection successfully closed
    -1: error while attempting to close connection
     

    sql_fetch()
    SIGNATURE: int sql_fetch (const string_o &sql, count_t &n, int *pi)
    SYNOPSIS: executes a SQL SELECT statement
    PARAMETERS

    • s: a string containing an SQL query
    • n: the number of resultant records
    • pi: error [output] indicator variable. The possible values are the same as that of member function 'sql_execute()'
    DESCRIPTION:
    this function is a convenience function. It is simply a shorthand way to simplify the call to "sql_execute()". This function should only be used when the sql query (in 'sql') is a SELECT statement. The internal cursors for the SQL query will remain open after this member function call.
     

    sql_execute()
    SIGNATURE: int sql_execute (const string_o &s, count_t &n, flag_o &f, int *pi = NULL)
    SYNOPSIS:
    executes an SQL statement. The object must have opened a database channel (see open()) prior to calling this function.
    PARAMETERS

    • s: a string, containing an SQL statement. This string should not be terminated with a semi-colon.
    • n: [output] the number of resultant records
    • f: [input] a set of flags that contain configuration parameters. The bit values are represented by these symbolic constants:
      zFlag_DBC_ExecFetch
      zFlag_DBC_ExecFirstFetch
      zFlag_DBC_ExecAutoClose
    • pi: [output] error indicator variable. values:
      0: SQL statement execution successfully completed
      zErr_Param_NotSet: input parameter string "s" is empty
      zErr_DB_Cannot_Open: no open connection
      3: COM/ODBC error occured (WARNING: this value is being phased out)
      [n>0]: any other positive value is the native error code of the underlying system. For example, a value of 1146 using ODBC indicates that a SELECT query was applied to a non-existant table.
    EXAMPLE:
    int i, ie, ie2; string_o server ("MAGIC"), db ("TESTBASE"); string_o user ("sa"), pwd("password");
    dbconnection_o x; ie = x.open(server, db, user, pwd, &ie); ie = x.sql_execute("SELECT count(*) FROM mytable");
    TRAITS: the error processing is lacking.
     

    sql_close()
    SIGNATURE: int sql_close (int *pi = NULL)
    SYNOPSIS: closes the current SQL query
    PARAMETERS

  • pi: error [output] indicator variable. values:
    0: closure successfully completed
    1: COM/ODBC error occured
  • DESCRIPTION: this should be done after a call to sql_execute(), and after the results have been examined.
     

    sql_fetch()
    SIGNATURE: int sql_fetch (int *pi = NULL)
    SYNOPSIS:
    moves to next record. this is used after a call to sql_execute(), when the resultant data is to be examined. Typically used for a SELECT statement that returns multiple rows.
    PARAMETERS

  • pi: error [output] indicator variable. values:
    0: fetch successfully completed
    1: no [more] data
    2: internal error (panic)
  • RETURNS:
    0: success; got data
    1: no more data
    -1: error (see value of pi for details)
     

    sql_numcolumns()
    SIGNATURE: count_t sql_numcolumns (int *pi = NULL)
    SYNOPSIS: returns the number of columns in query result set
    DESCRIPTION: this is used after a call to sql_execute(), when the output (resultant data set) is to be examined.
     

    sql_numrows()
    SIGNATURE: count_t sql_numrows (int *pi = NULL)
    SYNOPSIS: returns the number of rows in a query result set.
    DESCRIPTION:
    this is used after a call to sql_execute(), when the output (resultant data set) is to be examined. This function is an alternative to doing something like:

    while (x.sql_fetch() != -1
    
    (see example, on this page)
    WARNING: warning! this is *NOT IMPLEMENTED* for ADO! (sorry)
     

    sql_result_value()
    SIGNATURE: string_o sql_result_value (count_t, int *pi)
    SYNOPSIS: gets the value of a given column in the current record set, as a string object
    PARAMETERS

  • pi: error [output] indicator variable. values: 0: no errors
    1: ADO COM error occured (eg, no more records)
    2: ODBC error occured
    3: internal memory allocation error ('new' failed)
  • DESCRIPTION:
    this is used after a call to sql_execute(), when the output (resultant data set) is to be examined.
    WARNING: tests have indicated that the ADO version of sql_fetch() might not indicate an end-of-records condition on the last record. Hence, the 2nd parameter here has been made mandatory, and it is strongly urged to check it for an error condition (non-zero), which may indicate that there is no current record.
     

    sql_column_name()
    SIGNATURE: string_o sql_column_name (count_t x, int *pi)
    SYNOPSIS: ..
     

    sql_gotmore_data()
    SIGNATURE: boolean sql_gotmore_data (int *pi)
    SYNOPSIS: ..
     

    subclass_handle()
    SIGNATURE: dbconnection_o *subclass_handle () const
    SYNOPSIS: ..
     

    examples.
    In this example, the database server instance is "MAGIC" (in SQL Server, the default DB server name is oftentimes the same as the host computer's). On that server instance, the database to open is TESTBASE and we access it with [master] user account "sa", with the password "jetski". In the database TESTBASE we have craeted a table called MYTABLE.

    Note that we start by creating a dbconnection object to use ODBC, then we change our mind and opt for ADO. Also note that this code snippet is devoid of error checking.

    #include "z_dbconnect.h"
    void myfunction ()
    {
        int i, ie, ie2;
        string_o server ("MAGIC");
        string_o db ("TESTBASE");
        string_o user ("sa"), pwd("jetski");
        string_o sql ("SELECT * FROM mytable");
        string_o val;
        count_t n = 0;
        flag_o fla = 0;
        boolean all_done = FALSE;
    
        dbconnection_o x ("ODBC");                  // start out ODBC
        x.set_access_method (zstyle_DBax_ADO, &ie2);
        x.open(server, db, user, pwd, &ie);
        x.sql_execute(sql, n, fla);
    
        count_t num_cols = x.sql_numcolumns();
        while (x.sql_fetch() == 0 && !all_done)
        {
            for (i = 0; i < num_cols; ++i)
            {
                if (i > 0)
                    std::cout << ",\t";
    
                val = x.sql_result_value(i, &ie);
                if (!ie)
                    std::cout << "\"" << val << "\"";
                else
                    { all_done = TRUE; break; }
            }
    
            std::cout << std::endl;
        }
    }
    

    bugs.
    The resultant error codes after most database operations have not (but can) be examined and passed to the error indicator output variable. This is a deficiency that is planned to be corrected in a future release.