home *** CD-ROM | disk | FTP | other *** search
/ PC World 1999 May / PCWorld_1999-05_cd.bin / software / Vyzkuste / inprise / INTRBASE_55 / EXAMPLES / API / API14.E < prev    next >
Text File  |  1998-10-18  |  6KB  |  234 lines

  1. /*
  2.  *    Program type:  API Interface
  3.  *
  4.  *    Description:
  5.  *        This program combines the three programming styles:
  6.  *        static SQL, dynamic SQL, and the API interface.
  7.  *
  8.  *        Employee information is retrieved and printed for some set
  9.  *        of employees.  A predefined set of columns is always printed.
  10.  *        However, the 'where' clause, defining which employees the report
  11.  *        is to be printed for, is unknown.
  12.  *
  13.  *        Dynamic SQL is utilized to construct the select statement.
  14.  *        The 'where' clause is assumed to be passed as a parameter.
  15.  *
  16.  *        Static SQL is used for known SQL statements.
  17.  *
  18.  *        The API interface is used to access the two databases, and
  19.  *        to control most transactions.  The database and transaction
  20.  *        handles are shared between the three interfaces.
  21.  */
  22.  
  23. #include <stdlib.h>
  24. #include <string.h>
  25. #include <stdio.h>
  26. #include "example.h"
  27.  
  28. #define BUFLEN        1024
  29.  
  30. char    *sel_str =
  31.     "SELECT full_name, dept_no, salary, job_code, job_grade, job_country \
  32.      FROM employee";
  33.  
  34. char    *where_str =
  35.     "WHERE job_code = 'SRep' AND dept_no IN (110, 140, 115, 125, 123, 121)";
  36.  
  37. /* This macro is used to declare structures representing SQL VARCHAR types */
  38. #define SQL_VARCHAR(len) struct {short vary_length; char vary_string[(len)+1];}
  39.  
  40. char    Db_name[128];
  41.  
  42. EXEC SQL
  43.     SET DATABASE db1 = "employee.gdb" RUNTIME :Db_name;
  44.  
  45.  
  46.  
  47. int main(ARG(int, argc), ARG(char **, argv))
  48. ARGLIST(int argc)
  49. ARGLIST(char **argv)
  50. {
  51.     BASED_ON employee.salary        salary;
  52.     SQL_VARCHAR(5)                job_code;
  53.     BASED_ON employee.job_grade        job_grade;
  54.     SQL_VARCHAR(15)                job_country;
  55.     SQL_VARCHAR(37)                full_name;
  56.     BASED_ON country.currency        currency;
  57.     BASED_ON department.dept_no        dept_no;
  58.     BASED_ON department.department        department;
  59.     char    buf[BUFLEN + 1];
  60.     float    rate;
  61.     void    *trans1 = NULL;            /* transaction handle */
  62.     void    *trans2 = NULL;            /* transaction handle */
  63.     long    status[20];
  64.     XSQLDA    *sqlda;
  65.         char    empdb2[128];
  66.  
  67.         if (argc > 1)
  68.                 strcpy(Db_name, argv[1]);
  69.         else
  70.                 strcpy(Db_name, "employee.gdb");
  71.         if (argc > 2)
  72.                 strcpy(empdb2, argv[2]);
  73.         else
  74.                 strcpy(empdb2, "employe2.gdb");
  75.  
  76.  
  77.     EXEC SQL
  78.         WHENEVER SQLERROR GO TO Error;
  79.  
  80.     /*
  81.      *    Set-up the select query.  The select portion of the query is
  82.      *    static, while the 'where' clause is determined elsewhere and
  83.      *    passed as a parameter.
  84.      */
  85.      sprintf(buf, "%s %s", sel_str, where_str);
  86.  
  87.  
  88.     /*
  89.      *    Open the employee database.
  90.      */
  91.     if (isc_attach_database(status, 0, Db_name, &db1, 0, NULL))
  92.         isc_print_status(status);
  93.  
  94.     /*
  95.      *    Prepare the select query.
  96.      */
  97.  
  98.     sqlda = (XSQLDA *) malloc(XSQLDA_LENGTH(6));
  99.     sqlda->sqln = 6;
  100.     sqlda->sqld = 6;
  101.     sqlda->version = 1;
  102.  
  103.     EXEC SQL
  104.         SET TRANSACTION USING db1;
  105.     EXEC SQL
  106.         PREPARE q INTO SQL DESCRIPTOR sqlda FROM :buf;
  107.     EXEC SQL
  108.         COMMIT ;
  109.  
  110.     sqlda->sqlvar[0].sqldata = (char *)&full_name;
  111.     sqlda->sqlvar[0].sqltype = SQL_VARYING;
  112.  
  113.     sqlda->sqlvar[1].sqldata = dept_no;
  114.     sqlda->sqlvar[1].sqltype = SQL_TEXT;
  115.  
  116.     sqlda->sqlvar[2].sqldata = (char *) &salary;
  117.     sqlda->sqlvar[2].sqltype = SQL_DOUBLE;
  118.  
  119.     sqlda->sqlvar[3].sqldata = (char *)&job_code;
  120.     sqlda->sqlvar[3].sqltype = SQL_VARYING;
  121.  
  122.     sqlda->sqlvar[4].sqldata = (char *) &job_grade;
  123.     sqlda->sqlvar[4].sqltype = SQL_SHORT;
  124.  
  125.     sqlda->sqlvar[5].sqldata = (char *)&job_country;
  126.     sqlda->sqlvar[5].sqltype = SQL_VARYING;
  127.  
  128.  
  129.     /*
  130.      *    Open the second database.
  131.      */
  132.  
  133.     EXEC SQL
  134.             SET DATABASE db2 = "employe2.gdb";
  135.  
  136.     if (isc_attach_database(status, 0, empdb2, &db2, 0, NULL))
  137.         isc_print_status(status);
  138.  
  139.  
  140.     /*
  141.      *    Select the employees, using the dynamically allocated SQLDA.
  142.      */
  143.  
  144.     EXEC SQL
  145.         DECLARE emp CURSOR FOR q;
  146.      
  147.     if (isc_start_transaction(status, &trans1, 1, &db1, 0, NULL))
  148.         isc_print_status(status);
  149.  
  150.     EXEC SQL
  151.         OPEN TRANSACTION trans1 emp;
  152.  
  153.     while (SQLCODE == 0)
  154.     {
  155.         EXEC SQL
  156.             FETCH emp USING SQL DESCRIPTOR sqlda;
  157.  
  158.         if (SQLCODE == 100)
  159.             break;
  160.  
  161.         /*
  162.          *    Get the department name, using a static SQL statement.
  163.          */
  164.         EXEC SQL
  165.             SELECT TRANSACTION trans1 department
  166.             INTO :department
  167.             FROM department
  168.             WHERE dept_no = :dept_no;
  169.  
  170.         /*
  171.          *    If the job country is not USA, access the second database
  172.          *    in order to get the conversion rate between different money
  173.          *    types.  Even though the conversion rate may fluctuate, all
  174.          *    salaries will be presented in US dollars for relative comparison.
  175.          */
  176.         job_country.vary_string[job_country.vary_length] = '\0';
  177.         if (strcmp(job_country.vary_string, "USA"))
  178.         {
  179.             EXEC SQL
  180.                 SELECT TRANSACTION trans1 currency
  181.                 INTO :currency
  182.                 FROM country
  183.                 WHERE country = :job_country.vary_string :job_country.vary_length;
  184.  
  185.             if (isc_start_transaction(status, &trans2, 1, &db2, 0, NULL))
  186.                 isc_print_status(status);
  187.  
  188.             EXEC SQL
  189.                 SELECT TRANSACTION trans2 conv_rate
  190.                 INTO :rate
  191.                 FROM cross_rate
  192.                 WHERE from_currency = 'Dollar'
  193.                 AND to_currency = :currency;
  194.  
  195.             if (!SQLCODE)
  196.                 salary = salary / rate;
  197.  
  198.             if (isc_commit_transaction (status, &trans2))
  199.                 isc_print_status(status);
  200.         }
  201.  
  202.         /*
  203.          *    Print the results.
  204.          */
  205.  
  206.         printf("%-20.*s ", full_name.vary_length, full_name.vary_string);
  207.         fflush (stdout);
  208.         printf("%8.2f ", salary);
  209.         fflush (stdout);
  210.         printf("   %-5.*s %d", job_code.vary_length, job_code.vary_string, job_grade);
  211.         fflush (stdout);
  212.         printf("    %-20s\n", department);
  213.         fflush (stdout);
  214.     }
  215.  
  216.     EXEC SQL
  217.         CLOSE emp;
  218.      
  219.     if (isc_commit_transaction (status, &trans1))
  220.         isc_print_status(status);
  221.  
  222.     isc_detach_database(status, &db1);
  223.     isc_detach_database(status, &db2);
  224.  
  225.     return(0);
  226.  
  227.  
  228. Error:
  229.     printf("\n");
  230.     isc_print_sqlerror(SQLCODE, isc_status);
  231.     return(1);
  232. }
  233.  
  234.