home *** CD-ROM | disk | FTP | other *** search
/ Freelog 42 / Freelog042.iso / Alu / Ancestrologie / Sources / InterBase_WI-V6.0.1-server.ZIP / examples / api / api6.c < prev    next >
C/C++ Source or Header  |  2001-01-05  |  8KB  |  264 lines

  1. /*
  2.  *    Program type:  API Interface
  3.  *
  4.  *    Description:
  5.  *        This program performs a positioned update.
  6.  *        Department budgets are examined and updated using some
  7.  *        percent increase factor, determined at run-time.
  8.  *
  9.  *        The update statement is constructed using a dynamic cursor
  10.  *        name.  The statement handle is freed and re-used by the
  11.  *        update cursor, after being used by another statement.
  12.  * The contents of this file are subject to the Interbase Public
  13.  * License Version 1.0 (the "License"); you may not use this file
  14.  * except in compliance with the License. You may obtain a copy
  15.  * of the License at http://www.Inprise.com/IPL.html
  16.  *
  17.  * Software distributed under the License is distributed on an
  18.  * "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express
  19.  * or implied. See the License for the specific language governing
  20.  * rights and limitations under the License.
  21.  *
  22.  * The Original Code was created by Inprise Corporation
  23.  * and its predecessors. Portions created by Inprise Corporation are
  24.  *
  25.  * Copyright (C) 2000 Inprise Corporation
  26.  * All Rights Reserved.
  27.  * Contributor(s): ______________________________________.
  28.  */
  29.  
  30.  
  31. #include <stdlib.h>
  32. #include <string.h>
  33. #include <ibase.h>
  34. #include <stdio.h>
  35. #include "example.h"
  36.  
  37. #define    DEPTLEN        3
  38. #define    PROJLEN        5
  39. #define    BUFLEN        256
  40.  
  41. float increase_factor (double budget);
  42.  
  43. /*
  44.  *  A cursor is declared on this select statement, allowing for
  45.  *  the update of projected_budget field.
  46.  */
  47. char *sel_str =
  48.     "SELECT proj_id, dept_no, projected_budget \
  49.      FROM proj_dept_budget WHERE fiscal_year = 1994 \
  50.      FOR UPDATE OF projected_budget";
  51.  
  52. /* This query is executed prior to the positioned update. */
  53. char *tot_str =
  54.     "SELECT SUM(projected_budget) FROM proj_dept_budget WHERE fiscal_year = 1994";
  55.  
  56.  
  57.  
  58. int main (ARG(int, argc), ARG(char **,argv))
  59. ARGLIST(int argc)
  60. ARGLIST(char **argv)
  61. {
  62.     char                dept_no[DEPTLEN + 2];
  63.     char                proj_id[PROJLEN + 2];
  64.     char                upd_str[BUFLEN];
  65.     double              budget;
  66.     double              tot_budget;
  67.     short               flag0 = 0,
  68.                         flag1 = 0,
  69.                         flag2 = 0,
  70.                         flag3 = 0;
  71.     isc_db_handle       DB = NULL;              /* Database handle */
  72.     isc_tr_handle       trans = NULL;           /* transaction handle */
  73.     long                status[20];             /* status vector */
  74.     char                *cursor = "budget";     /* dynamic cursor name */
  75.     isc_stmt_handle     stmt = NULL;            /* statement handle */
  76.     XSQLDA  ISC_FAR *   osqlda;                 /* output SQLDA */
  77.     XSQLDA  ISC_FAR *   isqlda;                 /* input SQLDA */
  78.     long                fetch_stat;
  79.     char                empdb[128];
  80.  
  81.     if (argc > 1)
  82.         strcpy(empdb, argv[1]);
  83.     else
  84.         strcpy(empdb, "employee.gdb");
  85.  
  86.  
  87.     if (isc_attach_database(status, 0, empdb, &DB, 0, NULL))
  88.     {
  89.         ERREXIT(status, 1)
  90.     }
  91.  
  92.     /*
  93.      *    Prepare and execute the first select statement.
  94.      *    Free the statement handle, when done.
  95.      */
  96.  
  97.     if (isc_dsql_allocate_statement(status, &DB, &stmt))
  98.     {
  99.         ERREXIT(status, 1)
  100.     }
  101.  
  102.     osqlda = (XSQLDA *) malloc(XSQLDA_LENGTH(1));
  103.     osqlda->sqln = 1;
  104.     osqlda->sqld = 1;
  105.     osqlda->version = 1;
  106.  
  107.     if (isc_start_transaction(status, &trans, 1, &DB, 0, NULL))
  108.     {
  109.         ERREXIT(status, 1)
  110.     }
  111.  
  112.     if (isc_dsql_prepare(status, &trans, &stmt, 0, tot_str, 1, osqlda))
  113.         isc_print_status(status);
  114.  
  115.     osqlda->sqlvar[0].sqldata = (char *) &tot_budget;
  116.     osqlda->sqlvar[0].sqltype = SQL_DOUBLE + 1;
  117.     osqlda->sqlvar[0].sqllen  = sizeof(budget);
  118.     osqlda->sqlvar[0].sqlind  = &flag3;
  119.  
  120.     if (isc_dsql_execute(status, &trans, &stmt, 1, NULL))
  121.     {
  122.         ERREXIT(status, 1)
  123.     }
  124.  
  125.     fetch_stat = isc_dsql_fetch(status, &stmt, 1, osqlda);
  126.  
  127.     printf("\nTotal budget:  %16.2f\n\n", tot_budget);
  128.  
  129.     if (isc_dsql_free_statement(status, &stmt, DSQL_close))
  130.     {
  131.         ERREXIT(status, 1)
  132.     }
  133.  
  134.     if (isc_commit_transaction(status, &trans))
  135.     {
  136.         ERREXIT(status, 1)
  137.     }
  138.  
  139.     /*
  140.      *    Prepare and execute the positioned update.
  141.      *    Re-use the statement handle as the select cursor.
  142.      */
  143.  
  144.     sprintf(upd_str, "UPDATE proj_dept_budget SET projected_budget = ? \
  145.             WHERE CURRENT OF %s", cursor);
  146.  
  147.     /* Allocate an input SQLDA for the update statement. */
  148.     isqlda = (XSQLDA ISC_FAR *) malloc(XSQLDA_LENGTH(1));
  149.     isqlda->sqln = isqlda->sqld = 1;
  150.     isqlda->version = 1;
  151.  
  152.     isqlda->sqlvar[0].sqldata = (char ISC_FAR *) &budget;
  153.     isqlda->sqlvar[0].sqltype = SQL_DOUBLE + 1;
  154.     isqlda->sqlvar[0].sqllen  = sizeof(budget);
  155.     isqlda->sqlvar[0].sqlind  = &flag3;
  156.                               
  157.     /* Free the output SQLDA, which was used previously. */
  158.     free(osqlda);
  159.  
  160.     /* Re-allocate the output SQLDA. */
  161.     osqlda = (XSQLDA ISC_FAR*) malloc(XSQLDA_LENGTH(3));
  162.     osqlda->sqln = 3;
  163.     osqlda->sqld = 3;
  164.     osqlda->version = 1;
  165.  
  166.     osqlda->sqlvar[0].sqldata = proj_id;
  167.     osqlda->sqlvar[0].sqlind  = &flag0;
  168.  
  169.     osqlda->sqlvar[1].sqldata = dept_no;
  170.     osqlda->sqlvar[1].sqlind  = &flag1;
  171.  
  172.     osqlda->sqlvar[2].sqldata = (char ISC_FAR *) &budget;
  173.     osqlda->sqlvar[2].sqlind  = &flag2;
  174.                               
  175.     if (isc_start_transaction(status, &trans, 1, &DB, 0, NULL))
  176.     {
  177.         ERREXIT(status, 1)
  178.     }
  179.  
  180.     /* Zero the statement handle. */
  181.     stmt = NULL;
  182.  
  183.     if (isc_dsql_allocate_statement(status, &DB, &stmt))
  184.         isc_print_status(status);
  185.     
  186.     if (isc_dsql_prepare(status, &trans, &stmt, 0, sel_str, 1, osqlda))
  187.         isc_print_status(status);
  188.                
  189.     /* Declare the cursor. */
  190.     isc_dsql_set_cursor_name(status, &stmt, cursor, 0);
  191.  
  192.     if (isc_dsql_execute(status, &trans, &stmt, 1, NULL))
  193.     {
  194.         ERREXIT(status, 1)
  195.     }
  196.  
  197.     printf("\n%-15s%-10s%-18s%-18s\n\n",
  198.            "PROJ", "DEPT", " CURRENT BUDGET",  "  CHANGED TO");
  199.  
  200.     /*
  201.      *    Fetch and update department budgets.
  202.      */
  203.  
  204.     while ((fetch_stat = isc_dsql_fetch(status, &stmt, 1, osqlda)) == 0)
  205.     {
  206.         /* Determine the increase percentage. */
  207.         proj_id[PROJLEN] = '\0';
  208.         dept_no[DEPTLEN] = '\0';
  209.         printf("%-15s%-10s%15.2f", proj_id, dept_no, budget);
  210.         budget = budget + budget * increase_factor(budget);
  211.         printf("%15.2f\n", budget);
  212.  
  213.         /* Increase the budget. */
  214.         isc_dsql_exec_immed2(status, &DB, &trans, 0, upd_str, 1, isqlda, NULL);
  215.  
  216.         if (isc_sqlcode(status) == -625)
  217.         {
  218.             printf("\tExceeded budget limit -- not updated.\n");
  219.             continue;
  220.         }
  221.         else
  222.             isc_print_status(status);
  223.     }
  224.  
  225.     if (fetch_stat != 100L)
  226.     {
  227.         ERREXIT(status, 1)
  228.     }
  229.  
  230.     if (isc_dsql_free_statement(status, &stmt, DSQL_close))
  231.     {
  232.         ERREXIT(status, 1)
  233.     }
  234.  
  235.     if (isc_rollback_transaction(status, &trans))
  236.     {
  237.         ERREXIT(status, 1)
  238.     }
  239.  
  240.     if (isc_detach_database(status, &DB))
  241.     {
  242.         ERREXIT(status, 1)
  243.     }
  244.  
  245.     free(osqlda);
  246.     free(isqlda);
  247.  
  248.     return 0;
  249. }
  250.     
  251. /*
  252.  *    Determine a percent increase for the department's budget.
  253.  */
  254. float increase_factor (ARG(double, budget))
  255. ARGLIST(double    budget)
  256. {
  257.     if (budget < 100000L)
  258.         return (float)0.15;
  259.     else if (budget < 500000L)
  260.         return (float)0.10;
  261.     else 
  262.         return (float)0.5;
  263. }
  264.