Programmer's Guide to the Oracle7 Server Call Interface | ![]() Library |
![]() Product |
![]() Contents |
![]() Index |
gets((char *) sql_statement); if (*sql_statement != 'y' && *sql_statement != 'Y') do_exit(EXIT_SUCCESS); /* Parse, set defflg parameter for non-deferred parse (to execute the DDL statement immediately). */ if (oparse(&cda, (text *) "DROP TABLE voice_mail", -1, FALSE, 2)) { if (cda.rc == 942) fputs("Table did not exist.\n", stdout); else oci_error(&cda); } else fputs("Dropped table \"voice_mail\".\n", stdout); strcpy((char *) sql_statement, "CREATE TABLE voice_mail\ (msg_id NUMBER(6), msg_len NUMBER(12), msg LONG RAW)"); if (oparse(&cda, sql_statement, -1, FALSE, 2)) oci_error(&cda); fputs("Created table \"voice_mail\".\n", stdout); /* Create a dummy message. */ strcpy((char *) sql_statement, "INSERT INTO voice_mail (msg_id, msg_len, msg) \ VALUES (:1, :2, :3)"); if (oparse(&cda, sql_statement, -1, FALSE, 2)) oci_error(&cda); if (obndrn(&cda, 1, (ub1 *) &msg_id, 4, 3, -1, (sb2 *) 0, (text *) 0, 0, -1)) oci_error(&cda); /* Set buffer address before binding. */ ucp = (ub1 *) malloc(MSG_SIZE); if (ucp == 0) { fputs("malloc error\n", stderr); do_exit(EXIT_FAILURE); } if (obndrn(&cda, 2, (ub1 *) &msg_len, 4, 3, -1, (sb2 *) 0, (text *) 0, 0, -1)) oci_error(&cda); if (obndrn(&cda, 3, ucp, MSG_SIZE, 24, -1, (sb2 *) 0, (text *) 0, 0, -1)) oci_error(&cda); /* Set bind vars before oexn. */ msg_id = 100; msg_len = MSG_SIZE; for (i = 0, ucp1 = ucp; i < MSG_SIZE; i++) *ucp1++ = (ub1) i % 128; if (oexn(&cda, 1, 0)) oci_error(&cda); fputs("Data inserted in table \"voice_mail\".\n", stdout);
/* * After setting up the test data, do the * select and fetch the message chunks */ strcpy((char *) sql_statement, "select msg_id, msg_len, msg\ from voice_mail where msg_id = 100"); if (oparse(&cda, sql_statement, -1, 0, 2)) oci_error(&cda); if (odefin(&cda, 1, /* index */ (ub1 *) &msg_id, /* output variable */ 4, /* length */ 3, /* datatype */ -1, /* scale */ (sb2 *) 0, /* indp */ (text *) 0, /* fmt */ 0, /* fmtl */ -1, /* fmtt */ (ub2 *) 0, /* retl */ (ub2 *) 0)) /* rcode */ oci_error(&cda); if (odefin(&cda, 2, /* index */ (ub1 *) &msg_len,/* output variable */ 4, /* length */ 3, /* datatype */ -1, /* scale */ (sb2 *) 0, /* indp */ (text *) 0, /* fmt */ 0, /* fmtl */ -1, /* fmtt */ (ub2 *) 0, /* retl */ (ub2 *) 0)) /* rcode */ oci_error(&cda);
if (odefin(&cda, 3, /* index */ ucp, /* output variable */ 100, /* length */ 24, /* LONG RAW datatype code */ -1, /* scale */ &indp, /* indp */ (text *) 0, /* fmt */ 0, /* fmtl */ -1, /* fmtt */ &retl, /* retl */ &rcode)) /* rcode */ oci_error(&cda); /* Do the query, getting the msg_id and the first 100 bytes of the message. */ if (oexfet(&cda, (ub4) 1, /* nrows */ 0, /* cancel (FALSE) */ 0)) /* exact (FALSE) */ { oci_error(&cda); } fprintf(stdout, "Message %d is available, length is %d.\n", msg_id, msg_len); fprintf(stdout, "indp = %d, rcode = %d, retl = %d\n", indp, rcode, retl); /* Play the message, looping until there are no more data points to output. */ for (offset = (ub4) 0; ; offset += (ub4) 0x10000) { len = msg_len < 0x10000 ? msg_len : 0x10000; if (oflng(&cda, 3, /* position */ ucp, /* buf */ len, /* bufl */ 24, /* datatype */ &ret_len, /* retl */ offset)) /* offset */ oci_error(&cda); /* Output the message chunk. */ play_msg(ucp, len); msg_len -= len; if (msg_len <= 0) break; } do_exit(EXIT_SUCCESS); } dvoid play_msg(buf, len) ub1 *buf; sword len; { fprintf(stdout, "\"playing\" %d bytes.\n", len); }
dvoid oci_error(cda) Cda_Def *cda; { text msg[200]; sword n; fputs("\n-- ORACLE ERROR --\n", stderr); n = oerhms(&lda, (sb2) cda->rc, msg, 200); fprintf(stderr, "%.*s", n, msg); fprintf(stderr, "Processing OCI function %s\n", oci_func_tab[(int) cda->fc]); do_exit(EXIT_FAILURE); } dvoid do_exit(rv) sword rv; { fputs("Exiting...\n", stdout); if (oclose(&cda)) { fputs("Error closing cursor.\n", stderr); rv = EXIT_FAILURE; } if (ologof(&lda)) { fputs("Error logging off.\n", stderr); rv = EXIT_FAILURE; } exit(rv); }
/* cdemo4.c * * Demonstrates doing a FETCH from a cursor * into PL/SQL tables. The tables are bound to C * arrays using the obndra routine. * The fully-commented script to create the stored procedure * is in the demo program file calldemo.sql. * * Execute this script using SQL*DBA or SQL*Plus * to store the package before executing this program. * * The script is: * create or replace package calldemo as * * type char_array is table of varchar2(20) index by * binary_integer; * type num_array is table of float index by binary_integer; * * procedure get_employees( * dept_number in integer, -- which department to query * batch_size in integer, -- how many rows at a time * found in out integer, -- n of rows actually * returned * done_fetch out integer, -- all done flag * emp_name out char_array,-- arrays of employee names, * job out char_array,-- jobs, * sal out num_array);-- salaries * * end; * / * * create or replace package body calldemo as * * cursor get_emp( * dept_number in integer) is * select ename, job, sal from emp * where deptno = dept_number; * * -- Procedure get_employees fetches a batch of employee * -- rows (batch size is determined by the client/caller * -- of this procedure). Procedure may be called from * -- other stored procedures or client application * -- programs. The procedure opens the cursor if it is * -- not already open, fetches a batch of rows, and * -- returns the number of rows actually retrieved. At * -- end of fetch, the procedure closes the cursor. * * procedure get_employees( * dept_number in integer, * batch_size in integer, * found in out integer, * done_fetch out integer, * emp_name out char_array, * job out char_array, * sal out num_array) is * * begin * if NOT get_emp%ISOPEN then -- open the cursor if it is * open get_emp(dept_number); -- not already open * end if; * * -- Fetch up to "batch_size" rows into PL/SQL table, * -- tallying rows found as they are retrieved. When end * -- of fetch is encountered, close the cursor and exit * -- the loop, returning only the last set of rows found. * * done_fetch := FALSE; * found := 0; * for i in 1..batch_size loop * fetch get_emp -- get one emp table row * into emp_name(i), job(i), sal(i); * * if get_emp%notfound then -- if no row was found, then * close get_emp; -- close the cursor * done_fetch := TRUE; -- indicate all done * exit; -- exit the loop * else * found := found + 1; -- else count the row and * continue * end if; * end loop; * end; * end; * / */ #include <stdio.h> #include <string.h> #include <oratypes.h> #include <ocidfn.h> #ifdef __STDC__ #include <ociapr.h> #else #include <ocikpr.h> #endif #include <ocidem.h> #define MAX_ARRAY_SIZE 5 #define NO_PARSE_DEFER 0 #define V7_LNGFLG 2 #define VC_LENGTH 20 /* Declare the data areas. */ Cda_Def cda; Lda_Def lda; ub1 hda[512];
/* Declare routines in this program */ dvoid do_fetch(/*_ void _*/); dvoid oci_error(/*_ void _*/); main(argc, argv) sword argc; text **argv; { text username[128]; if (argc > 1) strncpy((char *) username, (char *) argv[1], sizeof (username) - 1); else strcpy((char *) username, "SCOTT/TIGER"); if (olog(&lda, hda, username, -1, (text *) 0, -1, (text *) 0, -1, OCI_LM_DEF)) { printf("Cannot connect as %s. Exiting...\n", username); exit(-1); } else printf("Connected.\n"); /* Open the OCI cursor. */ if (oopen(&cda, &lda, (text *) 0, -1, -1, (text *) 0, -1)) { printf("Cannot open cursor data area, exiting...\n"); exit(-1); } /* Fetch and print the data. */ do_fetch();
/* Close the OCI cursor. */ if (oclose(&cda)) { printf("Error closing cursor!\n"); exit(-1); } /* Disconnect from ORACLE. */ if (ologof(&lda)) { printf("Error logging off!\n"); exit(-1); } exit(0); } /* Set up an anonymous PL/SQL call to the stored procedure that fetches the data. */ dvoid do_fetch(/*_ void _*/) { text *call_fetch = (text *) "\ begin\ calldemo.get_employees(:deptno, :t_size, :num_ret,\ :all_done, :e_name, :job, :sal);\ end;"; sword table_size = MAX_ARRAY_SIZE; sword i, n_ret, done_flag; sword dept_num; sb2 n_ret_indp; ub2 n_ret_len, n_ret_rcode; ub4 n_ret_cursiz = 0; text emp_name[MAX_ARRAY_SIZE][VC_LENGTH]; sb2 emp_name_indp[MAX_ARRAY_SIZE]; ub2 emp_name_len[MAX_ARRAY_SIZE]; ub2 emp_name_rcode[MAX_ARRAY_SIZE]; ub4 emp_name_cursiz = (ub4) MAX_ARRAY_SIZE; text job[MAX_ARRAY_SIZE][VC_LENGTH]; sb2 job_indp[MAX_ARRAY_SIZE]; ub2 job_len[MAX_ARRAY_SIZE]; ub2 job_rcode[MAX_ARRAY_SIZE]; ub4 job_cursiz = (ub4) MAX_ARRAY_SIZE; float salary[MAX_ARRAY_SIZE]; sb2 salary_indp[MAX_ARRAY_SIZE]; ub2 salary_len[MAX_ARRAY_SIZE]; ub2 salary_rcode[MAX_ARRAY_SIZE]; ub4 salary_cursiz = (ub4) MAX_ARRAY_SIZE; /* parse the anonymous SQL block */ if (oparse(&cda, call_fetch, -1, NO_PARSE_DEFER, V7_LNGFLG)) { oci_error(); return; } /* initialize the bind arrays */ for (i = 0; i < MAX_ARRAY_SIZE; i++)
{ emp_name_len[i] = VC_LENGTH; job_len[i] = VC_LENGTH; salary_len[i] = sizeof (float); } n_ret_len = sizeof (sword); /* bind the department number IN parameter */ if (obndrv(&cda, (text *) ":deptno", -1, (ub1 *) &dept_num, (sword) sizeof (sword), INT_TYPE, -1, (sb2 *) 0, (text *) 0, -1, -1)) { oci_error(); return; } /* bind the table size IN parameter */ if (obndrv(&cda, (text *) ":t_size", -1, (ub1 *) &table_size, (sword) sizeof (sword), INT_TYPE, -1, (sb2 *) 0, (text *) 0, -1, -1)) { oci_error(); return; } /* bind the fetch done OUT parameter */ if (obndrv(&cda, (text *) ":all_done", -1, (ub1 *) &done_flag, (sword) sizeof (sword), INT_TYPE, -1, (sb2 *) 0, (text *) 0, -1, -1)) { oci_error(); return; } /* Bind the OUT n_ret using obndra. obndrv could have been used just as well, since no arrays are involved, but it is possible to use obndra for scalars as well. */ if (obndra(&cda, (text *) ":num_ret", -1, (ub1 *) &n_ret, (sword) sizeof (sword), INT_TYPE, -1, &n_ret_indp, &n_ret_len, &n_ret_rcode, (ub4) 0, /* pass as 0, not 1, when binding a scalar */ (ub4 *) 0, /* pass as the null pointer when scalar */ (text *) 0, -1, -1)) { oci_error(); return; } /* bind the employee name array */ if (obndra(&cda, (text *) ":e_name", -1, (ub1 *) emp_name, VC_LENGTH, VARCHAR2_TYPE, -1, emp_name_indp, emp_name_len, emp_name_rcode, (ub4) MAX_ARRAY_SIZE, &emp_name_cursiz, (text *) 0, -1, -1)) { oci_error(); return; }
/* bind the job array */ if (obndra(&cda, (text *) ":job", -1, (ub1 *) job, VC_LENGTH, VARCHAR2_TYPE, -1, job_indp, job_len, job_rcode, (ub4) MAX_ARRAY_SIZE, &job_cursiz, (text *) 0, -1, -1)) { oci_error(); return; } /* bind the salary array */ if (obndra(&cda, (text *) ":sal", -1, (ub1 *) salary, (sword) sizeof (float), FLOAT_TYPE, -1, salary_indp, salary_len, salary_rcode, (ub4) MAX_ARRAY_SIZE, &salary_cursiz, (text *) 0, -1, -1)) { oci_error(); return; } printf("\nenter deptno: "); scanf("%d", &dept_num); for (;;) { /* execute the fetch */ if (oexec(&cda)) { oci_error(); return; } printf("\n%d row%c returned\n", n_ret, n_ret == 1 ? '\0' : 's'); if (n_ret > 0) { printf("\n%-*.*s%-*.*s%s\n", VC_LENGTH, VC_LENGTH, "Employee Name", VC_LENGTH, VC_LENGTH, "Job", " Salary"); for (i = 0; i < n_ret; i++) { printf("%.*s", emp_name_len[i], emp_name[i]); printf("%*c", VC_LENGTH - emp_name_len[i], ' '); printf("%.*s", job_len[i], job[i]); printf("%*c", VC_LENGTH - job_len[i], ' '); printf("%8.2f\n", salary[i]); } } if (done_flag != 0) { printf("\n"); break; } } return; } dvoid oci_error(/*_ void _*/) { text msg[900]; sword rv; rv = oerhms(&lda, cda.rc, msg, (sword) sizeof (msg)); printf("\n\n%.*s", rv, msg); printf("Processing OCI function %s\n", oci_func_tab[(int) cda.fc]); return; }
/* * -- cdemo5.c -- * * An example program which demonstrates the use of * Variable Cursors in an OCI program. * */ #include <stdio.h> #include <stdlib.h> #include <ctype.h> #include <oratypes.h> #include <ocidfn.h> #include <ocikpr.h> /* oparse flags */ #define DEFER_PARSE 1 #define VERSION_7 2 #define NPOS 16 #define DSCLEN 240 text *username = (text *) "SCOTT"; text *password = (text *) "TIGER"; static sword retval; static ub1 hstb[512]; static text errorb[4095]; static text cbuf[NPOS][DSCLEN]; static sb4 cbufl[NPOS]; static sb4 dbsize[NPOS]; static sb4 dsize[NPOS]; static sb2 dbtype[NPOS]; static sb2 prec[NPOS]; static sb2 scale[NPOS]; static sb2 nullok[NPOS]; static Lda_Def lda1; static text plsql_block[] = "begin \ OPEN :cursor1 FOR select empno, ename, job, mgr, hiredate,sal,deptno\ from emp where job=:job order by empno;\ end;"; /* CLIENT CURSORS */ static Cda_Def cursor, cursor_emp; /* Prototype */ void oracle_error(); int main () { Lda_Def *ldap = &lda1; ub4 empno; text ename[11]; text job[10]; ub4 mgr; text hidate[10]; ub4 sal; ub4 deptno; int i; text job_kind[50]; ub4 pos; strcpy((char *) job_kind, "ANALYST"); fprintf(stdout,"\n\nFETCHING for job=%s\n\n",job_kind); /* Connect to Oracle as SCOTT/TIGER. * * Exit on any error. */ if (olog(ldap, hstb, username, -1, password, -1, (text *) 0, -1, OCI_LM_DEF)) { printf("Unable to connect as %s\n", username); exit(EXIT_FAILURE); } printf("Connected to Oracle as %s\n\n", username); /* * Open a cursor for executing the PL/SQL block. */ if (oopen(&cursor, ldap, (text *) 0, -1, 0, (text *) 0, -1)) { oracle_error(&cursor); exit(EXIT_FAILURE); } /* Parse the PL/SQL block. */ if (oparse(&cursor, plsql_block, (sb4) -1, (sword) TRUE, (ub4) 2)) { oracle_error(&cursor); exit(EXIT_FAILURE); } /* * Bind a variable of cursor datatype, the cursor will be opened * inside the PL/SQL block. */ if (obndra(&cursor,(text *) ":cursor1", -1, (ub1 *) &cursor_emp, -1, SQLT_CUR, -1, (sb2 *) 0, (ub2 *) 0, (ub2 *) 0, (ub4) 0, (ub4 *) 0, (text *) 0, 0, 0)) { oracle_error(&cursor); exit(EXIT_FAILURE); } /* * Bind a variable of string datatype. */ if (obndra(&cursor, (text *) ":job", -1, (ub1 *) job_kind, -1, SQLT_STR, -1, (sb2 *) 0, (ub2 *) 0, (ub2 *) 0, (ub4) 0, (ub4 *) 0, (text *) 0, 0, 0)) { oracle_error(&cursor); exit(EXIT_FAILURE); } /* * Execute the PL/SQL block. */ if (oexec(&cursor)) { oracle_error(&cursor); exit(EXIT_FAILURE); } /* * Close the cursor on which the PL/SQL block executed. */ if (oclose(&cursor)) { oracle_error(&cursor); exit(EXIT_FAILURE); }
/* * Do describe on cursor initialized and returned from the PL/SQL block. */ for (pos = 0; pos < NPOS; pos++) { cbufl[pos] = DSCLEN; if (odescr(&cursor_emp, (sword) (pos+1), &dbsize[pos], &dbtype[pos],(sb1 *) cbuf[pos], &cbufl[pos], &dsize[pos], &prec[pos], &scale[pos], &nullok[pos])) { if (cursor_emp.rc == 1007) break; oracle_error(&cursor_emp); exit(EXIT_FAILURE); } } printf("Describe select-list returns:\n\n"); printf("----------------------------------------\n"); printf("Item\t\tMaxSize\t\tType\n"); printf("----------------------------------------\n"); for (i = 0; i < pos; i++) { cbuf[i][cbufl[i]] = '\0'; printf("%s\t\t%d\t\t%d\n", cbuf[i], dbsize[i], dbtype[i]); } /* * Do client defines. */ if (odefin(&cursor_emp, 1, (ub1 *) &empno, (sword) sizeof(ub4), SQLT_INT, -1, (sb2 *) -1, (text *) 0, (sword) 0, (sword) 0, (ub2 *) 0,(ub2 *) 0)) { oracle_error(&cursor_emp); exit(EXIT_FAILURE); } if (odefin(&cursor_emp, 2, (ub1 *) ename, (sword) sizeof(ename), SQLT_STR, -1, (sb2 *) -1, (text *)0, (sword) 0, (sword) 0,(ub2 *) 0, (ub2 *) 0)) { oracle_error(&cursor_emp); exit(EXIT_FAILURE); }
if (odefin(&cursor_emp, 3, (ub1 *) job, (sword) sizeof(job), SQLT_STR, -1, (sb2 *) -1, (text *) 0, (sword) 0, (sword) 0, (ub2 *) 0, (ub2 *) 0)) { oracle_error(&cursor_emp); exit(EXIT_FAILURE); } if (odefin(&cursor_emp, 4, (ub1 *)&mgr, (sword) sizeof(ub4), SQLT_INT, -1, (sb2 *) -1, (text *)0, (sword) 0, (sword) 0, (ub2 *) 0, (ub2 *) 0)) { oracle_error(&cursor_emp); exit(EXIT_FAILURE); } if (odefin(&cursor_emp, 5, (ub1 *)hidate, (sword)sizeof(hidate), SQLT_STR, -1, (sb2 *) -1, (text *) 0, (sword) 0, (sword) 0, (ub2 *) 0, (ub2 *) 0)) { oracle_error(&cursor_emp); exit(EXIT_FAILURE); } if (odefin(&cursor_emp, 6, (ub1 *) &sal, (sword) sizeof(ub4), SQLT_INT, -1, (sb2 *) -1, (text *) 0, (sword) 0, (sword) 0, (ub2 *) 0, (ub2 *) 0)) { oracle_error(&cursor_emp); exit(EXIT_FAILURE); } if (odefin(&cursor_emp, 7, (ub1 *) &deptno, (sword)sizeof(deptno), SQLT_INT, -1, (sb2 *) -1, (text *) 0, (sword) 0, (sword) 0, (ub2 *) 0, (ub2 *) 0)) { oracle_error(&cursor_emp); exit(EXIT_FAILURE); } printf("\nFETCH from variable cursor:\n\n"); printf("------------------------------------------------------------\n"); printf("empno\tename\tjob\tmgr\thiredate\tsalary\tdept\n"); printf("------------------------------------------------------------\n"); /* * Now fetch the result set and display. */ while (1) { sb4 err = 0; if (err = ofetch(&cursor_emp)) { if (cursor_emp.rc == 1403) break; else { oracle_error(&cursor_emp); exit(EXIT_FAILURE); } } else { /* A row was returned; have to do the fetch. */ fprintf(stdout, "%d\t%s\t%s\t%d\t%s\t%d\t%d\n\n", empno, ename, job, mgr, hidate, sal, deptno); } } /* * Log off. */ if (ologof(ldap)) { oracle_error(&cursor_emp); exit(EXIT_FAILURE); } } /* end of main */ void oracle_error(lda) Lda_Def * lda; { char msgbuf[512]; int n=oerhms(lda, lda->rc, msgbuf, (int) sizeof(msgbuf) ); printf("\n\n%.*s\n",n,msgbuf); }
/* -- cdemo6.cc -- * An example program which illustrates how a C++ program * can use the OCI interface to access ORACLE database. * * This program retrieves department name, given the * department number. * * The program queries the user for data as follows: * * Enter department number: * * The program terminates if -1 is entered * when the department number is requested. */
extern "C" { #include <stdio.h> #include <oratypes.h> #include <ociapr.h> /* demo constants and structs */ #include <ocidem.h> }
extern "C" { #include <oratypes.h> #include <ocidfn.h> #include <ocidem.h> }
/* oparse flags */ #define DEFER_PARSE 1 #define NATIVE 1 #define VERSION_7 2
/* Class forward declarations */ class connection; class cursor;
/* * This class represents a connection to ORACLE database. * * NOTE: This connection class is just given as an example and * all possible operations on a connection have not been defined. */ class connection { friend class cursor; public: connection() { state = not_connected; } ~connection(); sword connect(const text *username, const text *password); sword disconnect(); void display_error(FILE* file) const; private: Lda_Def lda; ub1 hda[HDA_SIZE]; enum conn_state { not_connected, connected }; conn_state state; };
/* * This class represents an ORACLE cursor. * * NOTE: This cursor class is just given as an example and all * possible operations on a cursor have not been defined. */ class cursor { public: cursor() {state = not_opened; conn = (connection *)0; } ~cursor(); sword open(connection *conn_param); sword close(); sword parse(const text *stmt) { return (oparse(&cda, (text *)stmt, (sb4)-1, DEFER_PARSE, (ub4) VERSION_7)); } /* bind an input variable */ sword bind_by_position(sword sqlvnum, ub1 *progvar, sword progvarlen, sword datatype, sword scale, sb2 *indicator) { return (obndrn(&cda, sqlvnum, progvar, progvarlen, datatype, scale, indicator, (text *)0, -1, -1)); } /* define an output variable */ sword define_by_position(sword position, ub1 *buf, sword bufl, sword datatype, sword scale, sb2 *indicator, ub2 *rlen, ub2 *rcode) { return (odefin(&cda, position, buf, bufl, datatype, scale, indicator, (text *)0, -1, -1, rlen, rcode)); } sword describe(sword position, sb4 *dbsize, sb2 *dbtype, sb1 *cbuf, sb4 *cbufl, sb4 *dsize, sb2 *prec, sb2 *scale, sb2 *nullok) { return (odescr(&cda, position, dbsize, dbtype, cbuf, cbufl, dsize, prec, scale, nullok)); } sword execute() { return (oexec(&cda)); } sword fetch() { return (ofetch(&cda)); } sword get_error_code() const { return (cda.rc); } void display_error( FILE* file) const; private: Cda_Def cda; connection *conn; enum cursor_state { not_opened, opened }; cursor_state state; };
/* Error number macros */ #define CONERR_ALRCON -1 /* already connected */ #define CONERR_NOTCON -2 /* not connected */ #define CURERR_ALROPN -3 /* cursor is already open */ #define CURERR_NOTOPN -4 /* cursor is not opened */
/* exit status upon failure */ #define EXIT_FAILURE 1
const text *username = (text *) "SCOTT"; const text *password = (text *) "TIGER";
/* define SQL statements to be used in the program */ const text *seldept = (text *) "SELECT dname FROM dept WHERE deptno = :1";
void err_report(FILE *file, text *errmsg, sword func_code); void myfflush();
/* connection destructor */ connection::~connection() { // disconnect if connection exists if (state == connected) { if (disconnect()) { display_error(stderr); } } }
/* connect to ORACLE */ sword connection::connect(const text *username, const text *password) { sword status;
if (state == connected) { // this object is already connected return (CONERR_ALRCON); }
if ((status = olog(&lda, hda, (text *)username, -1 (text *)password, -1, (text *) 0, -1, OCI_LM_DEF)) == 0) { // successful login state = connected; printf("Connected to ORACLE as %s\n", username); }
return (status); }
/* disconnect from ORACLE */ sword connection::disconnect() { sword status;
if (state == not_connected) { // this object has not been connected return (CONERR_NOTCON); }
if ((status = ologof(&lda)) == 0) { // successful logout state = not_connected; }
return (status); }
/* write error message to the given file */ void connection::display_error(FILE *file) const { if (lda.rc != 0) { sword n; text msg[512];
n = oerhms((cda_def *)&lda, lda.rc, msg, (sword) sizeof(msg)); err_report(file, msg, lda.fc); } }
/* cursor destructor */ cursor::~cursor() { if (state == opened) { if (close()) display_error(stderr); } }
/* open the cursor */ sword cursor::open(connection *conn_param) { sword status;
if (state == opened) { // this cursor has already been opened return (CURERR_ALROPN); }
if ((status = oopen(&cda, &conn_param->lda, (text *)0, -1, -1, (text *)0, -1)) == 0) { // successfull open state = opened; conn = conn_param; }
return (status); }
/* close the cursor */ sword cursor::close() { sword status;
if (state == not_opened) { // this cursor has not been opened return (CURERR_NOTOPN); }
if ((status = oclose(&cda)) == 0) { // successful cursor close state = not_opened; conn = (connection *)0; }
return (status); }
/* write error message to the given file */ void cursor::display_error(FILE *file) const { if (cda.rc != 0) { sword n; text msg[512];
n = oerhms(&conn->lda, cda.rc, msg, (sword) sizeof(msg)); err_report(file, msg, cda.fc); } }
int main() { sword deptno; sword len, dsize; sb4 deptlen; sb2 db_type; sb1 name_buf[20]; text *dept;
/* * Connect to ORACLE and open a cursor. * Exit on any error. */ connection conn; if (conn.connect(username, password)) { conn.display_error(stderr); return(EXIT_FAILURE); }
cursor crsr; if (crsr.open(&conn)) { crsr.display_error(stderr); return(EXIT_FAILURE); }
/* parse the SELDEPT statement */ if (crsr.parse(seldept)) { crsr.display_error(stderr); return(EXIT_FAILURE); }
/* bind the placeholder in the SELDEPT statement */ if (crsr.bind_by_position(1, (ub1 *) &deptno, (sword) sizeof(deptno), INT_TYPE, -1, (sb2 *) 0)) { crsr.display_error(stderr); return(EXIT_FAILURE); }
/* describe the select-list field "dname" */ len = sizeof (name_buf); if (crsr.describe(1, (sb4 *) &deptlen, &db_type, name_buf, (sb4 *) &len, (sb4 *) &dsize, (sb2 *) 0, (sb2 *) 0, (sb2 *) 0)) { crsr.display_error(stderr); return(EXIT_FAILURE); }
/* allocate space for dept name now that you have length */ dept = new text((int) deptlen + 1);
/* define the output variable for the select-list */ if (crsr.define_by_position(1, (ub1 *) dept, (sword)deptlen+1, STRING_TYPE, -1, (sb2 *) 0, (ub2 *) 0, (ub2 *) 0)) { crsr.display_error(stderr); delete dept; return(EXIT_FAILURE); }
for (;;) { /* prompt for department number, */ /* break if given number == -1 */ printf("\nEnter department number (or -1 to EXIT): "); while (scanf("%d", &deptno) != 1) { myfflush(); printf("Invalid input, please enter a number \ (-1 to EXIT): "); } if (deptno == -1) { printf("Exiting... "); break; }
/* display the name of the corresponding department */ if (crsr.execute() || crsr.fetch()) { if (crsr.get_error_code() != NO_DATA_FOUND) { crsr.display_error(stderr); delete dept; return(EXIT_FAILURE); } else printf("\n The department number that you entered \ doesn't exist.\n"); } else { printf("\n Department name = %s \ Department number = %d\n", dept, deptno); } }
delete dept; printf ("\nG'day\n");
return 0; }
void err_report(FILE *file, text *errmsg, sword func_code) { fprintf(file, "\n-- ORACLE error--\n\n%s\n", errmsg); if (func_code > 0) fprintf(file, "Processing OCI function %s\n", oci_func_tab[func_code]); }
void myfflush() { eb1 buf[50]; fgets((char *) buf, 50, stdin); }
![]() ![]() Prev Next |
![]() Copyright © 1996 Oracle Corporation. All Rights Reserved. |
![]() Library |
![]() Product |
![]() Contents |
![]() Index |