home *** CD-ROM | disk | FTP | other *** search
- /*
- * Program type: API Interface
- *
- * Description:
- * This program performs a positioned update.
- * Department budgets are examined and updated using some
- * percent increase factor, determined at run-time.
- *
- * The update statement is constructed using a dynamic cursor
- * name. The statement handle is freed and re-used by the
- * update cursor, after being used by another statement.
- */
-
-
- #include <stdlib.h>
- #include <string.h>
- #include <ibase.h>
- #include <stdio.h>
- #include "example.h"
-
- #define DEPTLEN 3
- #define PROJLEN 5
- #define BUFLEN 256
-
- float increase_factor PROTO((double budget));
-
- /*
- * A cursor is declared on this select statement, allowing for
- * the update of projected_budget field.
- */
- char *sel_str =
- "SELECT proj_id, dept_no, projected_budget \
- FROM proj_dept_budget WHERE year = 1994 \
- FOR UPDATE OF projected_budget";
-
- /* This query is executed prior to the positioned update. */
- char *tot_str =
- "SELECT SUM(projected_budget) FROM proj_dept_budget WHERE year = 1994";
-
-
-
- int main (ARG(int, argc), ARG(char **,argv))
- ARGLIST(int argc)
- ARGLIST(char **argv)
- {
- char dept_no[DEPTLEN + 2];
- char proj_id[PROJLEN + 2];
- char upd_str[BUFLEN];
- double budget;
- double tot_budget;
- short flag0 = 0,
- flag1 = 0,
- flag2 = 0,
- flag3 = 0;
- isc_db_handle DB = NULL; /* Database handle */
- isc_tr_handle trans = NULL; /* transaction handle */
- long status[20]; /* status vector */
- char *cursor = "budget"; /* dynamic cursor name */
- isc_stmt_handle stmt = NULL; /* statement handle */
- XSQLDA ISC_FAR * osqlda; /* output SQLDA */
- XSQLDA ISC_FAR * isqlda; /* input SQLDA */
- long fetch_stat;
- char empdb[128];
-
- if (argc > 1)
- strcpy(empdb, argv[1]);
- else
- strcpy(empdb, "employee.gdb");
-
-
- if (isc_attach_database(status, 0, empdb, &DB, 0, NULL))
- {
- ERREXIT(status, 1)
- }
-
- /*
- * Prepare and execute the first select statement.
- * Free the statement handle, when done.
- */
-
- if (isc_dsql_allocate_statement(status, &DB, &stmt))
- {
- ERREXIT(status, 1)
- }
-
- osqlda = (XSQLDA *) malloc(XSQLDA_LENGTH(1));
- osqlda->sqln = 1;
- osqlda->sqld = 1;
- osqlda->version = 1;
-
- if (isc_start_transaction(status, &trans, 1, &DB, 0, NULL))
- {
- ERREXIT(status, 1)
- }
-
- if (isc_dsql_prepare(status, &trans, &stmt, 0, tot_str, 1, osqlda))
- isc_print_status(status);
-
- osqlda->sqlvar[0].sqldata = (char *) &tot_budget;
- osqlda->sqlvar[0].sqltype = SQL_DOUBLE + 1;
- osqlda->sqlvar[0].sqllen = sizeof(budget);
- osqlda->sqlvar[0].sqlind = &flag3;
-
- if (isc_dsql_execute(status, &trans, &stmt, 1, NULL))
- {
- ERREXIT(status, 1)
- }
-
- fetch_stat = isc_dsql_fetch(status, &stmt, 1, osqlda);
-
- printf("\nTotal budget: %16.2f\n\n", tot_budget);
-
- if (isc_dsql_free_statement(status, &stmt, DSQL_close))
- {
- ERREXIT(status, 1)
- }
-
- if (isc_commit_transaction(status, &trans))
- {
- ERREXIT(status, 1)
- }
-
- /*
- * Prepare and execute the positioned update.
- * Re-use the statement handle as the select cursor.
- */
-
- sprintf(upd_str, "UPDATE proj_dept_budget SET projected_budget = ? \
- WHERE CURRENT OF %s", cursor);
-
- /* Allocate an input SQLDA for the update statement. */
- isqlda = (XSQLDA ISC_FAR *) malloc(XSQLDA_LENGTH(1));
- isqlda->sqln = isqlda->sqld = 1;
- isqlda->version = 1;
-
- isqlda->sqlvar[0].sqldata = (char ISC_FAR *) &budget;
- isqlda->sqlvar[0].sqltype = SQL_DOUBLE + 1;
- isqlda->sqlvar[0].sqllen = sizeof(budget);
- isqlda->sqlvar[0].sqlind = &flag3;
-
- /* Free the output SQLDA, which was used previously. */
- free(osqlda);
-
- /* Re-allocate the output SQLDA. */
- osqlda = (XSQLDA ISC_FAR*) malloc(XSQLDA_LENGTH(3));
- osqlda->sqln = 3;
- osqlda->sqld = 3;
- osqlda->version = 1;
-
- osqlda->sqlvar[0].sqldata = proj_id;
- osqlda->sqlvar[0].sqlind = &flag0;
-
- osqlda->sqlvar[1].sqldata = dept_no;
- osqlda->sqlvar[1].sqlind = &flag1;
-
- osqlda->sqlvar[2].sqldata = (char ISC_FAR *) &budget;
- osqlda->sqlvar[2].sqlind = &flag2;
-
- if (isc_start_transaction(status, &trans, 1, &DB, 0, NULL))
- {
- ERREXIT(status, 1)
- }
-
- /* Zero the statement handle. */
- stmt = NULL;
-
- if (isc_dsql_allocate_statement(status, &DB, &stmt))
- isc_print_status(status);
-
- if (isc_dsql_prepare(status, &trans, &stmt, 0, sel_str, 1, osqlda))
- isc_print_status(status);
-
- /* Declare the cursor. */
- isc_dsql_set_cursor_name(status, &stmt, cursor, 0);
-
- if (isc_dsql_execute(status, &trans, &stmt, 1, NULL))
- {
- ERREXIT(status, 1)
- }
-
- printf("\n%-15s%-10s%-18s%-18s\n\n",
- "PROJ", "DEPT", " CURRENT BUDGET", " CHANGED TO");
-
- /*
- * Fetch and update department budgets.
- */
-
- while ((fetch_stat = isc_dsql_fetch(status, &stmt, 1, osqlda)) == 0)
- {
- /* Determine the increase percentage. */
- proj_id[PROJLEN] = '\0';
- dept_no[DEPTLEN] = '\0';
- printf("%-15s%-10s%15.2f", proj_id, dept_no, budget);
- budget = budget + budget * increase_factor(budget);
- printf("%15.2f\n", budget);
-
- /* Increase the budget. */
- isc_dsql_exec_immed2(status, &DB, &trans, 0, upd_str, 1, isqlda, NULL);
-
- if (isc_sqlcode(status) == -625)
- {
- printf("\tExceeded budget limit -- not updated.\n");
- continue;
- }
- else
- isc_print_status(status);
- }
-
- if (fetch_stat != 100L)
- {
- ERREXIT(status, 1)
- }
-
- if (isc_dsql_free_statement(status, &stmt, DSQL_close))
- {
- ERREXIT(status, 1)
- }
-
- if (isc_rollback_transaction(status, &trans))
- {
- ERREXIT(status, 1)
- }
-
- if (isc_detach_database(status, &DB))
- {
- ERREXIT(status, 1)
- }
-
- free(osqlda);
- free(isqlda);
-
- return 0;
- }
-
- /*
- * Determine a percent increase for the department's budget.
- */
- float increase_factor (ARG(double, budget))
- ARGLIST(double budget)
- {
- if (budget < 100000L)
- return (float)0.15;
- else if (budget < 500000L)
- return (float)0.10;
- else
- return (float)0.5;
- }
-