home *** CD-ROM | disk | FTP | other *** search
/ Chip 2001 January / Chip_2001-01_cd1.bin / tema / interb / InterBase_WI-V6.0-server.exe / server / examples / gpre / api14.e next >
Text File  |  2000-06-23  |  7KB  |  253 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.  * The contents of this file are subject to the Interbase Public
  22.  * License Version 1.0 (the "License"); you may not use this file
  23.  * except in compliance with the License. You may obtain a copy
  24.  * of the License at http://www.Interbase.com/IPL/
  25.  *
  26.  * Software distributed under the License is distributed on an
  27.  * "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express
  28.  * or implied. See the License for the specific language governing
  29.  * rights and limitations under the License.
  30.  *
  31.  * The Original Code was created by Interbase Software Corporation
  32.  * and its successors. Portions created by Borland/Inprise are
  33.  * Copyright (C) 1992-1998 and 1999-2000 Borland/Inprise. Portions
  34.  * created by InterBase Software Corporation are Copyright (C)
  35.  * 1998-1999 InterBase Software Corporation.
  36.  *
  37.  * Copyright (C) 2000 InterBase Software Corporation
  38.  * All Rights Reserved.
  39.  * Contributor(s): ______________________________________.
  40.  */
  41.  
  42. #include <stdlib.h>
  43. #include <string.h>
  44. #include <stdio.h>
  45. #include "example.h"
  46.  
  47. #define BUFLEN        1024
  48.  
  49. char    *sel_str =
  50.     "SELECT full_name, dept_no, salary, job_code, job_grade, job_country \
  51.      FROM employee";
  52.  
  53. char    *where_str =
  54.     "WHERE job_code = 'SRep' AND dept_no IN (110, 140, 115, 125, 123, 121)";
  55.  
  56. /* This macro is used to declare structures representing SQL VARCHAR types */
  57. #define SQL_VARCHAR(len) struct {short vary_length; char vary_string[(len)+1];}
  58.  
  59. char    Db_name[128];
  60.  
  61. EXEC SQL
  62.     SET DATABASE db1 = "employee.gdb" RUNTIME :Db_name;
  63.  
  64.  
  65.  
  66. int main(ARG(int, argc), ARG(char **, argv))
  67. ARGLIST(int argc)
  68. ARGLIST(char **argv)
  69. {
  70.     BASED_ON employee.salary        salary;
  71.     SQL_VARCHAR(5)                job_code;
  72.     BASED_ON employee.job_grade        job_grade;
  73.     SQL_VARCHAR(15)                job_country;
  74.     SQL_VARCHAR(37)                full_name;
  75.     BASED_ON country.currency        currency;
  76.     BASED_ON department.dept_no        dept_no;
  77.     BASED_ON department.department        department;
  78.     char    buf[BUFLEN + 1];
  79.     float    rate;
  80.     void    *trans1 = NULL;            /* transaction handle */
  81.     void    *trans2 = NULL;            /* transaction handle */
  82.     long    status[20];
  83.     XSQLDA    *sqlda;
  84.         char    empdb2[128];
  85.  
  86.         if (argc > 1)
  87.                 strcpy(Db_name, argv[1]);
  88.         else
  89.                 strcpy(Db_name, "employee.gdb");
  90.         if (argc > 2)
  91.                 strcpy(empdb2, argv[2]);
  92.         else
  93.                 strcpy(empdb2, "employe2.gdb");
  94.  
  95.  
  96.     EXEC SQL
  97.         WHENEVER SQLERROR GO TO Error;
  98.  
  99.     /*
  100.      *    Set-up the select query.  The select portion of the query is
  101.      *    static, while the 'where' clause is determined elsewhere and
  102.      *    passed as a parameter.
  103.      */
  104.      sprintf(buf, "%s %s", sel_str, where_str);
  105.  
  106.  
  107.     /*
  108.      *    Open the employee database.
  109.      */
  110.     if (isc_attach_database(status, 0, Db_name, &db1, 0, NULL))
  111.         isc_print_status(status);
  112.  
  113.     /*
  114.      *    Prepare the select query.
  115.      */
  116.  
  117.     sqlda = (XSQLDA *) malloc(XSQLDA_LENGTH(6));
  118.     sqlda->sqln = 6;
  119.     sqlda->sqld = 6;
  120.     sqlda->version = 1;
  121.  
  122.     EXEC SQL
  123.         SET TRANSACTION USING db1;
  124.     EXEC SQL
  125.         PREPARE q INTO SQL DESCRIPTOR sqlda FROM :buf;
  126.     EXEC SQL
  127.         COMMIT ;
  128.  
  129.     sqlda->sqlvar[0].sqldata = (char *)&full_name;
  130.     sqlda->sqlvar[0].sqltype = SQL_VARYING;
  131.  
  132.     sqlda->sqlvar[1].sqldata = dept_no;
  133.     sqlda->sqlvar[1].sqltype = SQL_TEXT;
  134.  
  135.     sqlda->sqlvar[2].sqldata = (char *) &salary;
  136.     sqlda->sqlvar[2].sqltype = SQL_DOUBLE;
  137.  
  138.     sqlda->sqlvar[3].sqldata = (char *)&job_code;
  139.     sqlda->sqlvar[3].sqltype = SQL_VARYING;
  140.  
  141.     sqlda->sqlvar[4].sqldata = (char *) &job_grade;
  142.     sqlda->sqlvar[4].sqltype = SQL_SHORT;
  143.  
  144.     sqlda->sqlvar[5].sqldata = (char *)&job_country;
  145.     sqlda->sqlvar[5].sqltype = SQL_VARYING;
  146.  
  147.  
  148.     /*
  149.      *    Open the second database.
  150.      */
  151.  
  152.     EXEC SQL
  153.             SET DATABASE db2 = "employe2.gdb";
  154.  
  155.     if (isc_attach_database(status, 0, empdb2, &db2, 0, NULL))
  156.         isc_print_status(status);
  157.  
  158.  
  159.     /*
  160.      *    Select the employees, using the dynamically allocated SQLDA.
  161.      */
  162.  
  163.     EXEC SQL
  164.         DECLARE emp CURSOR FOR q;
  165.      
  166.     if (isc_start_transaction(status, &trans1, 1, &db1, 0, NULL))
  167.         isc_print_status(status);
  168.  
  169.     EXEC SQL
  170.         OPEN TRANSACTION trans1 emp;
  171.  
  172.     while (SQLCODE == 0)
  173.     {
  174.         EXEC SQL
  175.             FETCH emp USING SQL DESCRIPTOR sqlda;
  176.  
  177.         if (SQLCODE == 100)
  178.             break;
  179.  
  180.         /*
  181.          *    Get the department name, using a static SQL statement.
  182.          */
  183.         EXEC SQL
  184.             SELECT TRANSACTION trans1 department
  185.             INTO :department
  186.             FROM department
  187.             WHERE dept_no = :dept_no;
  188.  
  189.         /*
  190.          *    If the job country is not USA, access the second database
  191.          *    in order to get the conversion rate between different money
  192.          *    types.  Even though the conversion rate may fluctuate, all
  193.          *    salaries will be presented in US dollars for relative comparison.
  194.          */
  195.         job_country.vary_string[job_country.vary_length] = '\0';
  196.         if (strcmp(job_country.vary_string, "USA"))
  197.         {
  198.             EXEC SQL
  199.                 SELECT TRANSACTION trans1 currency
  200.                 INTO :currency
  201.                 FROM country
  202.                 WHERE country = :job_country.vary_string :job_country.vary_length;
  203.  
  204.             if (isc_start_transaction(status, &trans2, 1, &db2, 0, NULL))
  205.                 isc_print_status(status);
  206.  
  207.             EXEC SQL
  208.                 SELECT TRANSACTION trans2 conv_rate
  209.                 INTO :rate
  210.                 FROM cross_rate
  211.                 WHERE from_currency = 'Dollar'
  212.                 AND to_currency = :currency;
  213.  
  214.             if (!SQLCODE)
  215.                 salary = salary / rate;
  216.  
  217.             if (isc_commit_transaction (status, &trans2))
  218.                 isc_print_status(status);
  219.         }
  220.  
  221.         /*
  222.          *    Print the results.
  223.          */
  224.  
  225.         printf("%-20.*s ", full_name.vary_length, full_name.vary_string);
  226.         fflush (stdout);
  227.         printf("%8.2f ", salary);
  228.         fflush (stdout);
  229.         printf("   %-5.*s %d", job_code.vary_length, job_code.vary_string, job_grade);
  230.         fflush (stdout);
  231.         printf("    %-20s\n", department);
  232.         fflush (stdout);
  233.     }
  234.  
  235.     EXEC SQL
  236.         CLOSE emp;
  237.      
  238.     if (isc_commit_transaction (status, &trans1))
  239.         isc_print_status(status);
  240.  
  241.     isc_detach_database(status, &db1);
  242.     isc_detach_database(status, &db2);
  243.  
  244.     return(0);
  245.  
  246.  
  247. Error:
  248.     printf("\n");
  249.     isc_print_sqlerror(SQLCODE, isc_status);
  250.     return(1);
  251. }
  252.  
  253.