home *** CD-ROM | disk | FTP | other *** search
- /*
- * Program type: API Interface
- *
- * Description:
- * This program combines the three programming styles:
- * static SQL, dynamic SQL, and the API interface.
- *
- * Employee information is retrieved and printed for some set
- * of employees. A predefined set of columns is always printed.
- * However, the 'where' clause, defining which employees the report
- * is to be printed for, is unknown.
- *
- * Dynamic SQL is utilized to construct the select statement.
- * The 'where' clause is assumed to be passed as a parameter.
- *
- * Static SQL is used for known SQL statements.
- *
- * The API interface is used to access the two databases, and
- * to control most transactions. The database and transaction
- * handles are shared between the three interfaces.
- */
-
- #include <stdlib.h>
- #include <string.h>
- #include <stdio.h>
- #include "example.h"
-
- #define BUFLEN 1024
-
- char *sel_str =
- "SELECT full_name, dept_no, salary, job_code, job_grade, job_country \
- FROM employee";
-
- char *where_str =
- "WHERE job_code = 'SRep' AND dept_no IN (110, 140, 115, 125, 123, 121)";
-
- /* This macro is used to declare structures representing SQL VARCHAR types */
- #define SQL_VARCHAR(len) struct {short vary_length; char vary_string[(len)+1];}
-
- char Db_name[128];
-
- EXEC SQL
- SET DATABASE db1 = "employee.gdb" RUNTIME :Db_name;
-
-
-
- int main(ARG(int, argc), ARG(char **, argv))
- ARGLIST(int argc)
- ARGLIST(char **argv)
- {
- BASED_ON employee.salary salary;
- SQL_VARCHAR(5) job_code;
- BASED_ON employee.job_grade job_grade;
- SQL_VARCHAR(15) job_country;
- SQL_VARCHAR(37) full_name;
- BASED_ON country.currency currency;
- BASED_ON department.dept_no dept_no;
- BASED_ON department.department department;
- char buf[BUFLEN + 1];
- float rate;
- void *trans1 = NULL; /* transaction handle */
- void *trans2 = NULL; /* transaction handle */
- long status[20];
- XSQLDA *sqlda;
- char empdb2[128];
-
- if (argc > 1)
- strcpy(Db_name, argv[1]);
- else
- strcpy(Db_name, "employee.gdb");
- if (argc > 2)
- strcpy(empdb2, argv[2]);
- else
- strcpy(empdb2, "employe2.gdb");
-
-
- EXEC SQL
- WHENEVER SQLERROR GO TO Error;
-
- /*
- * Set-up the select query. The select portion of the query is
- * static, while the 'where' clause is determined elsewhere and
- * passed as a parameter.
- */
- sprintf(buf, "%s %s", sel_str, where_str);
-
-
- /*
- * Open the employee database.
- */
- if (isc_attach_database(status, 0, Db_name, &db1, 0, NULL))
- isc_print_status(status);
-
- /*
- * Prepare the select query.
- */
-
- sqlda = (XSQLDA *) malloc(XSQLDA_LENGTH(6));
- sqlda->sqln = 6;
- sqlda->sqld = 6;
- sqlda->version = 1;
-
- EXEC SQL
- SET TRANSACTION USING db1;
- EXEC SQL
- PREPARE q INTO SQL DESCRIPTOR sqlda FROM :buf;
- EXEC SQL
- COMMIT ;
-
- sqlda->sqlvar[0].sqldata = (char *)&full_name;
- sqlda->sqlvar[0].sqltype = SQL_VARYING;
-
- sqlda->sqlvar[1].sqldata = dept_no;
- sqlda->sqlvar[1].sqltype = SQL_TEXT;
-
- sqlda->sqlvar[2].sqldata = (char *) &salary;
- sqlda->sqlvar[2].sqltype = SQL_DOUBLE;
-
- sqlda->sqlvar[3].sqldata = (char *)&job_code;
- sqlda->sqlvar[3].sqltype = SQL_VARYING;
-
- sqlda->sqlvar[4].sqldata = (char *) &job_grade;
- sqlda->sqlvar[4].sqltype = SQL_SHORT;
-
- sqlda->sqlvar[5].sqldata = (char *)&job_country;
- sqlda->sqlvar[5].sqltype = SQL_VARYING;
-
-
- /*
- * Open the second database.
- */
-
- EXEC SQL
- SET DATABASE db2 = "employe2.gdb";
-
- if (isc_attach_database(status, 0, empdb2, &db2, 0, NULL))
- isc_print_status(status);
-
-
- /*
- * Select the employees, using the dynamically allocated SQLDA.
- */
-
- EXEC SQL
- DECLARE emp CURSOR FOR q;
-
- if (isc_start_transaction(status, &trans1, 1, &db1, 0, NULL))
- isc_print_status(status);
-
- EXEC SQL
- OPEN TRANSACTION trans1 emp;
-
- while (SQLCODE == 0)
- {
- EXEC SQL
- FETCH emp USING SQL DESCRIPTOR sqlda;
-
- if (SQLCODE == 100)
- break;
-
- /*
- * Get the department name, using a static SQL statement.
- */
- EXEC SQL
- SELECT TRANSACTION trans1 department
- INTO :department
- FROM department
- WHERE dept_no = :dept_no;
-
- /*
- * If the job country is not USA, access the second database
- * in order to get the conversion rate between different money
- * types. Even though the conversion rate may fluctuate, all
- * salaries will be presented in US dollars for relative comparison.
- */
- job_country.vary_string[job_country.vary_length] = '\0';
- if (strcmp(job_country.vary_string, "USA"))
- {
- EXEC SQL
- SELECT TRANSACTION trans1 currency
- INTO :currency
- FROM country
- WHERE country = :job_country.vary_string :job_country.vary_length;
-
- if (isc_start_transaction(status, &trans2, 1, &db2, 0, NULL))
- isc_print_status(status);
-
- EXEC SQL
- SELECT TRANSACTION trans2 conv_rate
- INTO :rate
- FROM cross_rate
- WHERE from_currency = 'Dollar'
- AND to_currency = :currency;
-
- if (!SQLCODE)
- salary = salary / rate;
-
- if (isc_commit_transaction (status, &trans2))
- isc_print_status(status);
- }
-
- /*
- * Print the results.
- */
-
- printf("%-20.*s ", full_name.vary_length, full_name.vary_string);
- fflush (stdout);
- printf("%8.2f ", salary);
- fflush (stdout);
- printf(" %-5.*s %d", job_code.vary_length, job_code.vary_string, job_grade);
- fflush (stdout);
- printf(" %-20s\n", department);
- fflush (stdout);
- }
-
- EXEC SQL
- CLOSE emp;
-
- if (isc_commit_transaction (status, &trans1))
- isc_print_status(status);
-
- isc_detach_database(status, &db1);
- isc_detach_database(status, &db2);
-
- return(0);
-
-
- Error:
- printf("\n");
- isc_print_sqlerror(SQLCODE, isc_status);
- return(1);
- }
-
-