home *** CD-ROM | disk | FTP | other *** search
/ NeXTSTEP 3.3 (Developer) / NeXT_Developer-3.3.iso / NextLibrary / Documentation / Sybase / DBLIB / Section2 / dbqual.nr < prev    next >
Encoding:
Text File  |  1993-04-22  |  5.6 KB  |  170 lines

  1. .Na "dbqual"
  2. .mc |
  3. .Aa
  4. .Fu
  5. Return a pointer to a WHERE clause suitable for use 
  6. in updating the current row in a browsable table.
  7. .Ih "WHERE clause, for use in updating a browsable table"
  8. .Ih "browse mode WHERE clause"
  9. .Sy
  10. .Sf "char *dbqual(dbproc, tabnum, tabname)"
  11. .Sp "DBPROCESS" "*dbproc"
  12. .Sp "int" "tabnum"
  13. .Sp "char" "*tabname"
  14. .Co
  15. .Bl
  16. \f2dbqual()\f1 is one of the \*L browse mode routines.
  17. See the Introduction for a detailed discussion of browse mode.
  18. .Bl
  19. \f2dbqual()\f1 provides a 
  20. WHERE clause that the application can use to update a single row in a browsable table.
  21. Columns from this row must have previously been retrieved into the application
  22. through a browse-mode SELECT query (\f2i.e.,\f1 a SELECT that ends with the key words
  23. FOR BROWSE).
  24. .sp 0.5v
  25. The WHERE clause produced by \f2dbqual()\f1 begins with the keyword WHERE
  26. and contains references to the row's unique index and timestamp column.
  27. .Ih "timestamp, browse mode"
  28. The application simply
  29. appends the WHERE clause to an UPDATE or DELETE statement; it does not
  30. need to examine it or manipulate it in any way.
  31. .sp 0.5v
  32. The timestamp column indicates the time that the particular row was last updated.
  33. An update on a browsable table will fail if the timestamp column in the \f2dbqual()\f1-generated
  34. WHERE clause is different from the timestamp column in the table.
  35. Such a condition, which provokes \*S error message 532,
  36. indicates that another user updated the row between
  37. the time this application selected it for browsing and the time it tried to update it.
  38. The application itself must provide the logic for handling the update failure.
  39. The following program fragment illustrates one approach:
  40. .SD
  41. .ta +4n +4n +4n +4n +4n +4n
  42. /* This code fragment illustrates a technique for handling the case where
  43.  * a browse-mode update fails because the row has already been updated
  44.  * by another user. In this example, we simply retrieve the entire row
  45.  * again, allow the user to examine and modify it, and try the update
  46.  * again.
  47.  *
  48.  * Note that "q_dbproc" is the DBPROCESS used to query the database, and
  49.  * "u_dbproc" is the DBPROCESS used to update the database.
  50.  */
  51.  
  52.     /* First, find out which employee record the user wants to update. */
  53.     employee_id = which_employee();
  54.  
  55.     while (1)
  56.     {
  57.         /* Retrieve that employee record from the database. We'll
  58.          * assume that "empid" is a unique index, so this query will
  59.          * return only one row.
  60.          */
  61.         dbfcmd
  62.          (q_dbproc,
  63.           "select * from employees where empid = %d for browse",
  64.           employee_id);
  65.         dbsqlexec(q_dbproc);
  66.         dbresults(q_dbproc);
  67.         dbnextrow(q_dbproc);
  68.  
  69.         /* Now, let the user examine or edit the employee's
  70.          * data, first placing the data into program variables.
  71.          */
  72.         extract_employee_data(q_dbproc, employee_struct);
  73.         examine_and_edit(employee_struct, &edit_flag);
  74.  
  75.         if (edit_flag == FALSE)
  76.         {
  77.             /* The user didn't edit this record,
  78.              * so we're done.
  79.              */
  80.             break;
  81.         }
  82.         else
  83.         {
  84.             /* The user edited this record, so we'll use the edited
  85.              * data to update the corresponding row in the database.
  86.              */
  87.             qualptr = dbqual(q_dbproc, -1, "employees");
  88.             dbcmd(u_dbproc, "update employees");
  89.             dbfcmd
  90.              (u_dbproc,
  91.               " set address = '%s', salary = %d %s",
  92.               employee_struct->address, employee_struct->salary,
  93.               qualptr);
  94.             dbfreequal(qualptr);
  95.             if ((dbsqlexec(u_dbproc) == FAIL)
  96.                 || (dbresults(u_dbproc) == FAIL))
  97.             {
  98.                 /* Our update failed. In a real program, it
  99.                  * would be necessary to examine the messages
  100.                  * returned from the SQL Server to determine
  101.                  * why it failed.  In this example, we'll 
  102.                  * assume that the update failed because
  103.                  * someone else has already updated this
  104.                  * row, thereby changing the timestamp.
  105.                  *
  106.                  * To cope with this situation, we'll just
  107.                  * repeat the loop, retrieving the changed
  108.                  * row for our user to examine and edit.
  109.                  * This will give our user the opportunity
  110.                  * to decide whether to overwrite the change 
  111.                  * made by the other user. 
  112.                  */
  113.                 continue;
  114.             }
  115.             else
  116.             {
  117.                 /* The update succeeded, so we're done. */
  118.                 break;
  119.             }
  120.         }
  121.     }
  122. .ED
  123. .Bl
  124. \f2dbqual()\f1 can only construct WHERE clauses for browsable tables.
  125. You can use \f2dbtabbrowse()\f1 to determine whether a table is browsable.
  126. .Bl
  127. \f2dbqual()\f1 is usually called after \f2dbnextrow()\f1.
  128. .Bl
  129. For a complete example that uses \f2dbqual()\f1 to perform a browse mode update, see Example 6 in the \f2\*L Reference Supplement\f1.
  130. .Bz
  131. .Pa
  132. .Pi dbproc
  133. A pointer to the DBPROCESS structure that provides the connection
  134. for a particular front-end/\*S process.  It contains all the
  135. information that \*L uses to manage communications and data between the
  136. front end and \*S.
  137. .Pi tabnum
  138. The number of the table of interest, as specified in the SELECT statement's FROM clause.
  139. Table numbers start at 1.
  140. If \f2tabnum\f1 is -1, the \f2tabname\f1 parameter will be
  141. used to identify the table.
  142. .Pi tabname 
  143. A pointer to the null-terminated name of a table specified in the SELECT statement's FROM clause. 
  144. If \f2tabname\f1 is NULL, 
  145. the \f2tabnum\f1 parameter will be used to identify the table.
  146. .in -.375i
  147. .Re
  148. .br
  149. A pointer to a null-terminated WHERE clause for the current
  150. row in the specified table. This buffer is dynamically allocated,
  151. and it is the application's responsibility to free it via \f2dbfreequal()\f1.
  152. .sp 0.5v
  153. \f2dbqual()\f1 will return a NULL pointer if the specified table is not browsable.
  154. For a table to be ``browsable,'' it must have a unique index and a timestamp column.
  155. .sp 0.5v
  156. \f2dbqual()\f1 will also return a NULL pointer if the preceding SELECT 
  157. did not include the FOR BROWSE option.
  158. .Sa
  159. dbcolbrowse,
  160. dbcolsource,
  161. dbfreequal,
  162. dbtabbrowse,
  163. dbtabcount,
  164. dbtabname,
  165. dbtabsource,
  166. dbtsnewlen,
  167. dbtsnewval,
  168. dbtsput
  169. .mc
  170.