dbqual

Returns a pointer to a WHERE clause to update the current row in a browsable table.

Syntax

LPCSTR dbqual (
PDBPROCESS
dbproc,
INT
tabnum,
LPCSTR
tabname );

where

dbproc
Is the DBPROCESS structure that is the handle for a particular workstation/ SQL Server process. It contains all the information that DB-Library uses to manage communications and data between the workstation and SQL Server.
tabnum
Is the number of the table, as specified in the SELECT statement's FROM clause. Table numbers start at 1. If tabnum is -1, the tabname parameter is used to identify the table.
tabname
Is a pointer to the null-terminated name of a table specified in the SELECT statement's FROM clause. If tabname is NULL, the tabnum parameter is used to identify the table.

Returns

A pointer to a null-terminated WHERE clause for the current row in the specified table. This buffer is dynamically allocated, and the application must free it by calling dbfreequal. If dbqual is asked to construct a WHERE clause for a table that cannot be browsed, it returns a NULL pointer. For details, see "dbtabbrowse."

Remarks

The dbqual function is one of the DB-Library browse-mode functions. For a discussion of browse mode, see Getting Started.

The dbqual function provides a WHERE clause that the application can use to update a single row in a browsable table. Columns from this row must have been previously retrieved through a browse-mode SELECT query.

The WHERE clause produced by dbqual begins with the keyword WHERE and contains references to the row's unique index and timestamp column. The application appends the WHERE clause to an UPDATE or DELETE statement without needing to examine or manipulate it in any way.

The timestamp column indicates the time that the particular row was last updated. An update on a browsable table fails if the timestamp column in the dbqual-generated WHERE clause is different from the timestamp column in the table. Such a condition, which provokes SQL Server error message 532, indicates that another user updated the row between the time this application selected it for browsing and the time it tried to update it. The application itself must provide the logic for handling the update failure. For one approach, see the example in the next section.

The dbqual function can construct WHERE clauses only for tables that can be browsed. Use dbtabbrowse to determine whether a table can be browsed.

The dbqual function is usually called after dbnextrow.

Example

This code fragment shows what to do when a browse-mode update fails because another user has already updated the row. This example retrieves the entire row again, allows the user to examine and modify it, and tries the update again.

Note that q_dbproc is the DBPROCESS used to query the database, and u_dbproc is the DBPROCESS used to update the database.

// First, find out which employee record the user wants to update. 
employee_id = which_employee();
while (1)
{
    // Retrieve that employee record from the database.
    // Assume that "empid" is a unique index, so this query will
    // return only one row.
    
    dbfcmd
    (q_dbproc,
    "select * from employees where empid = %d for browse",
    employee_id);
    dbsqlexec(q_dbproc);
    dbresults(q_dbproc);
    while (dbnextrow(q_dbproc)
        != NO_MORE_ROWS);

    // Now, let the user examine or edit the employee's
    // data, first placing the data into the program variables.
    
    extract_employee_data(q_dbproc, employee_struct);
    examine_and_edit(employee_struct, &edit_flag);

    if (edit_flag == FALSE)
    {
        // The user didn't edit this record,
        // so it's done.
        
        break;
    }
    else
    {
        // The user edited this record, so the application
        // uses the edited data to update the corresponding row
        // in the database.
         
        qualptr = dbqual(q_dbproc, -1, "employees");
        dbcmd(u_dbproc, "update employees");
        dbfcmd
        (u_dbproc,
        " set address = '%s', salary = %d %s",
        employee_struct->address, employee_struct->salary,
        qualptr);
        dbfreequal(qualptr);
        if ((dbsqlexec(u_dbproc) == FAIL)
        || (dbresults(u_dbproc) == FAIL))

        {
            // The update failed. In a real program, it
            // would be necessary to examine the messages
            // returned from SQL Server to determine
            // why it failed. In this example, 
            // assume that the update failed because
            // someone else has already updated this
            // row, thereby changing the timestamp.
            //
            // To cope with this situation, repeat
            // the loop, retrieving the changed row
            // for the user to examine and edit.
            // This will give the user the opportunity 
            // to decide whether to overwrite
            // the change made by the other user.
            
            continue;
        }
        else
        {
            // The update succeeded, so the
            // application is done. 
            break;
        }
    }
}

See Also

dbcolbrowse, dbcolsource, dbfreequal, dbnextrow, dbtabbrowse, dbtabcount, dbtabname, dbtabsource, dbtsnewlen, dbtsnewval, dbtsput; Bulk-Copy Functions