api14.e 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247
  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.Inprise.com/IPL.html
  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 Inprise Corporation
  32. * and its predecessors. Portions created by Inprise Corporation are
  33. * Copyright (C) Inprise Corporation.
  34. *
  35. * All Rights Reserved.
  36. * Contributor(s): ______________________________________.
  37. */
  38. #include <stdlib.h>
  39. #include <string.h>
  40. #include <stdio.h>
  41. #include "example.h"
  42. #define BUFLEN 1024
  43. char *sel_str =
  44. "SELECT full_name, dept_no, salary, job_code, job_grade, job_country \
  45. FROM employee";
  46. char *where_str =
  47. "WHERE job_code = 'SRep' AND dept_no IN (110, 140, 115, 125, 123, 121)";
  48. /* This macro is used to declare structures representing SQL VARCHAR types */
  49. #define SQL_VARCHAR(len) struct {short vary_length; char vary_string[(len)+1];}
  50. char Db_name[128];
  51. EXEC SQL
  52. SET DATABASE db1 = "employee.fdb" RUNTIME :Db_name;
  53. int main(int argc, char** argv)
  54. {
  55. BASED_ON employee.salary salary;
  56. SQL_VARCHAR(5) job_code;
  57. BASED_ON employee.job_grade job_grade;
  58. SQL_VARCHAR(15) job_country;
  59. SQL_VARCHAR(37) full_name;
  60. BASED_ON country.currency currency;
  61. BASED_ON department.dept_no dept_no;
  62. BASED_ON department.department department;
  63. char buf[BUFLEN + 1];
  64. float rate;
  65. void *trans1 = NULL; /* transaction handle */
  66. void *trans2 = NULL; /* transaction handle */
  67. ISC_STATUS_ARRAY status;
  68. XSQLDA *sqlda;
  69. char empdb2[128];
  70. if (argc > 1)
  71. strcpy(Db_name, argv[1]);
  72. else
  73. strcpy(Db_name, "employee.fdb");
  74. if (argc > 2)
  75. strcpy(empdb2, argv[2]);
  76. else
  77. strcpy(empdb2, "employe2.fdb");
  78. EXEC SQL
  79. WHENEVER SQLERROR GO TO Error;
  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. * Open the employee database.
  88. */
  89. if (isc_attach_database(status, 0, Db_name, &db1, 0, NULL))
  90. isc_print_status(status);
  91. /*
  92. * Prepare the select query.
  93. */
  94. sqlda = (XSQLDA *) malloc(XSQLDA_LENGTH(6));
  95. sqlda->sqln = 6;
  96. sqlda->sqld = 6;
  97. sqlda->version = 1;
  98. EXEC SQL
  99. SET TRANSACTION USING db1;
  100. EXEC SQL
  101. PREPARE q INTO SQL DESCRIPTOR sqlda FROM :buf;
  102. EXEC SQL
  103. COMMIT ;
  104. sqlda->sqlvar[0].sqldata = (char *)&full_name;
  105. sqlda->sqlvar[0].sqltype = SQL_VARYING;
  106. sqlda->sqlvar[1].sqldata = dept_no;
  107. sqlda->sqlvar[1].sqltype = SQL_TEXT;
  108. sqlda->sqlvar[2].sqldata = (char *) &salary;
  109. sqlda->sqlvar[2].sqltype = SQL_DOUBLE;
  110. sqlda->sqlvar[3].sqldata = (char *)&job_code;
  111. sqlda->sqlvar[3].sqltype = SQL_VARYING;
  112. sqlda->sqlvar[4].sqldata = (char *) &job_grade;
  113. sqlda->sqlvar[4].sqltype = SQL_SHORT;
  114. sqlda->sqlvar[5].sqldata = (char *)&job_country;
  115. sqlda->sqlvar[5].sqltype = SQL_VARYING;
  116. /*
  117. * Open the second database.
  118. */
  119. EXEC SQL
  120. SET DATABASE db2 = "employe2.fdb";
  121. if (isc_attach_database(status, 0, empdb2, &db2, 0, NULL))
  122. isc_print_status(status);
  123. /*
  124. * Select the employees, using the dynamically allocated SQLDA.
  125. */
  126. EXEC SQL
  127. DECLARE emp CURSOR FOR q;
  128. if (isc_start_transaction(status, &trans1, 1, &db1, 0, NULL))
  129. isc_print_status(status);
  130. EXEC SQL
  131. OPEN TRANSACTION trans1 emp;
  132. while (SQLCODE == 0)
  133. {
  134. EXEC SQL
  135. FETCH emp USING SQL DESCRIPTOR sqlda;
  136. if (SQLCODE == 100)
  137. break;
  138. /*
  139. * Get the department name, using a static SQL statement.
  140. */
  141. EXEC SQL
  142. SELECT TRANSACTION trans1 department
  143. INTO :department
  144. FROM department
  145. WHERE dept_no = :dept_no;
  146. /*
  147. * If the job country is not USA, access the second database
  148. * in order to get the conversion rate between different money
  149. * types. Even though the conversion rate may fluctuate, all
  150. * salaries will be presented in US dollars for relative comparison.
  151. */
  152. job_country.vary_string[job_country.vary_length] = '\0';
  153. if (strcmp(job_country.vary_string, "USA"))
  154. {
  155. EXEC SQL
  156. SELECT TRANSACTION trans1 currency
  157. INTO :currency
  158. FROM country
  159. WHERE country = :job_country.vary_string :job_country.vary_length;
  160. if (isc_start_transaction(status, &trans2, 1, &db2, 0, NULL))
  161. isc_print_status(status);
  162. EXEC SQL
  163. SELECT TRANSACTION trans2 conv_rate
  164. INTO :rate
  165. FROM cross_rate
  166. WHERE from_currency = 'Dollar'
  167. AND to_currency = :currency;
  168. if (!SQLCODE)
  169. salary = salary / rate;
  170. if (isc_commit_transaction (status, &trans2))
  171. isc_print_status(status);
  172. }
  173. /*
  174. * Print the results.
  175. */
  176. printf("%-20.*s ", full_name.vary_length, full_name.vary_string);
  177. fflush (stdout);
  178. printf("%8.2f ", salary);
  179. fflush (stdout);
  180. printf(" %-5.*s %d", job_code.vary_length, job_code.vary_string, job_grade);
  181. fflush (stdout);
  182. printf(" %-20s\n", department);
  183. fflush (stdout);
  184. }
  185. EXEC SQL
  186. CLOSE emp;
  187. if (isc_commit_transaction (status, &trans1))
  188. isc_print_status(status);
  189. isc_detach_database(status, &db1);
  190. isc_detach_database(status, &db2);
  191. return(0);
  192. Error:
  193. printf("\n");
  194. isc_print_sqlerror(SQLCODE, isc_status);
  195. return(1);
  196. }