source: liacs/db/opdr3/vb1.c@ 5

Last change on this file since 5 was 2, checked in by Rick van der Zwet, 15 years ago

Initial import of data of old repository ('data') worth keeping (e.g. tracking
means of URL access statistics)

  • Property svn:executable set to *
File size: 12.6 KB
RevLine 
[2]1
2/* Result Sets Interface */
3#ifndef SQL_CRSR
4# define SQL_CRSR
5 struct sql_cursor
6 {
7 unsigned int curocn;
8 void *ptr1;
9 void *ptr2;
10 unsigned long magic;
11 };
12 typedef struct sql_cursor sql_cursor;
13 typedef struct sql_cursor SQL_CURSOR;
14#endif /* SQL_CRSR */
15
16/* Thread Safety */
17typedef void * sql_context;
18typedef void * SQL_CONTEXT;
19
20/* Object support */
21struct sqltvn
22{
23 unsigned char *tvnvsn;
24 unsigned short tvnvsnl;
25 unsigned char *tvnnm;
26 unsigned short tvnnml;
27 unsigned char *tvnsnm;
28 unsigned short tvnsnml;
29};
30typedef struct sqltvn sqltvn;
31
32struct sqladts
33{
34 unsigned int adtvsn;
35 unsigned short adtmode;
36 unsigned short adtnum;
37 sqltvn adttvn[1];
38};
39typedef struct sqladts sqladts;
40
41static struct sqladts sqladt = {
42 1,1,0,
43};
44
45/* Binding to PL/SQL Records */
46struct sqltdss
47{
48 unsigned int tdsvsn;
49 unsigned short tdsnum;
50 unsigned char *tdsval[1];
51};
52typedef struct sqltdss sqltdss;
53static struct sqltdss sqltds =
54{
55 1,
56 0,
57};
58
59/* File name & Package Name */
60struct sqlcxp
61{
62 unsigned short fillen;
63 char filnam[7];
64};
65static const struct sqlcxp sqlfpn =
66{
67 6,
68 "vb1.pc"
69};
70
71
72static unsigned long sqlctx = 4611;
73
74
75static struct sqlexd {
76 unsigned int sqlvsn;
77 unsigned int arrsiz;
78 unsigned int iters;
79 unsigned int offset;
80 unsigned short selerr;
81 unsigned short sqlety;
82 unsigned int occurs;
83 const short *cud;
84 unsigned char *sqlest;
85 const char *stmt;
86 sqladts *sqladtp;
87 sqltdss *sqltdsp;
88 void **sqphsv;
89 unsigned int *sqphsl;
90 int *sqphss;
91 void **sqpind;
92 int *sqpins;
93 unsigned int *sqparm;
94 unsigned int **sqparc;
95 unsigned short *sqpadto;
96 unsigned short *sqptdso;
97 void *sqhstv[5];
98 unsigned int sqhstl[5];
99 int sqhsts[5];
100 void *sqindv[5];
101 int sqinds[5];
102 unsigned int sqharm[5];
103 unsigned int *sqharc[5];
104 unsigned short sqadto[5];
105 unsigned short sqtdso[5];
106} sqlstm = {10,5};
107
108// Prototypes
109extern "C" {
110 void sqlcxt (void **, unsigned long *,
111 struct sqlexd *, const struct sqlcxp *);
112 void sqlcx2t(void **, unsigned long *,
113 struct sqlexd *, const struct sqlcxp *);
114 void sqlbuft(void **, char *);
115 void sqlgs2t(void **, char *);
116 void sqlorat(void **, unsigned long *, void *);
117}
118
119// Forms Interface
120static const int IAPSUCC = 0;
121static const int IAPFAIL = 1403;
122static const int IAPFTL = 535;
123extern "C" { void sqliem(char *, int *); }
124
125typedef struct { unsigned short len; unsigned char arr[1]; } VARCHAR;
126typedef struct { unsigned short len; unsigned char arr[1]; } varchar;
127
128/* cud (compilation unit data) array */
129static const short sqlcud0[] =
130{10,4130,0,0,0,
1315,0,0,1,0,0,32,62,0,0,0,0,0,1,0,
13220,0,0,2,0,0,27,100,0,0,4,4,0,1,0,1,9,0,0,1,9,0,0,1,10,0,0,1,10,0,0,
13351,0,0,3,95,0,4,126,0,0,5,1,0,1,0,2,9,0,0,2,9,0,0,2,9,0,0,2,9,0,0,1,9,0,0,
13486,0,0,4,0,0,32,156,0,0,0,0,0,1,0,
135};
136
137
138/*
139 * vb1.pc
140 *
141 * Prompts the user for a branch number,
142 * then queries the branch table for the branch's
143 * address, phone and fax.
144 * 2003, Siegfried Nijssen (snijssen@liacs.nl)
145 */
146
147#include <iostream.h>
148#include <string.h>
149#include <stdlib.h>
150#include <sqlda.h>
151#include <sqlcpr.h>
152#include <sqlca.h>
153
154// Define constants for VARCHAR lengths.
155#define UNAME_LEN 20
156#define PWD_LEN 40
157
158//* Declare variables.
159
160/* EXEC SQL BEGIN DECLARE SECTION; */
161
162
163/* VARCHAR username[UNAME_LEN]; */
164struct { unsigned short len; unsigned char arr[20]; } username;
165
166/* VARCHAR password[PWD_LEN]; */
167struct { unsigned short len; unsigned char arr[40]; } password;
168
169
170// Define a host structure for the output values of a SELECT statement.
171struct
172{
173 /* VARCHAR branch_no[10]; */
174struct { unsigned short len; unsigned char arr[10]; } branch_no;
175
176 /* VARCHAR address[60]; */
177struct { unsigned short len; unsigned char arr[60]; } address;
178
179 /* VARCHAR phone[13]; */
180struct { unsigned short len; unsigned char arr[13]; } phone;
181
182 /* VARCHAR fax[13]; */
183struct { unsigned short len; unsigned char arr[13]; } fax;
184
185} branchrec;
186
187// Input host variable.
188/* VARCHAR branch_no[10]; */
189struct { unsigned short len; unsigned char arr[10]; } branch_no;
190
191
192/* EXEC SQL END DECLARE SECTION; */
193
194
195// Declare error handling function.
196void sql_error(char *msg)
197{
198 char err_msg[128];
199 size_t buf_len, msg_len;
200
201 /* EXEC SQL WHENEVER SQLERROR CONTINUE; */
202
203 /* after executing this line, sql_error is no longer used as
204 * error handling function. In this way, infinite
205 * recursion is avoided if the next SQL statement
206 * in this function fails.
207 */
208
209 // Print the error message:
210 cout << msg << endl;
211 buf_len = sizeof (err_msg);
212 sqlglm(err_msg, &buf_len, &msg_len);
213 cout << msg_len << "*" << err_msg << endl;
214
215 // Make sure the database is consistent:
216 /* EXEC SQL ROLLBACK RELEASE; */
217
218{
219 struct sqlexd sqlstm;
220 sqlstm.sqlvsn = 10;
221 sqlstm.arrsiz = 0;
222 sqlstm.sqladtp = &sqladt;
223 sqlstm.sqltdsp = &sqltds;
224 sqlstm.iters = (unsigned int )1;
225 sqlstm.offset = (unsigned int )5;
226 sqlstm.cud = sqlcud0;
227 sqlstm.sqlest = (unsigned char *)&sqlca;
228 sqlstm.sqlety = (unsigned short)256;
229 sqlstm.occurs = (unsigned int )0;
230 sqlcxt((void **)0, &sqlctx, &sqlstm, &sqlfpn);
231}
232
233
234
235 // Stop the program.
236 exit(EXIT_FAILURE);
237}
238
239void main()
240{
241 char temp_char[32]; /* strings are of type VARCHAR in Oracle and not \0
242 * terminated. We use this temporary variable
243 * whenever a \0 terminated string is necessary.
244 */
245
246
247 cout << "Enter your ORACLE username: " << endl;
248 cin >> temp_char;
249
250 /* Connect to ORACLE--
251 * Copy the username into the VARCHAR.
252 */
253 strncpy((char *) username.arr, temp_char, UNAME_LEN);
254
255 // Set the length component of the VARCHAR. This is always required!
256 username.len = (unsigned short) strlen((char *) username.arr);
257
258 cout << "Enter your ORACLE password: " << endl;
259 cin >> temp_char;
260
261 // Copy the password.
262 strncpy((char *) password.arr, temp_char, PWD_LEN);
263 password.len = (unsigned short) strlen((char *) password.arr);
264
265 // Register sql_error() as the error handler. */
266 /* EXEC SQL WHENEVER SQLERROR DO sql_error("ORACLE error--\n"); */
267
268
269 /* Connect to ORACLE. Program will call sql_error()
270 * if an error occurs when connecting to the default database.
271 */
272 /* EXEC SQL CONNECT :username IDENTIFIED BY :password; */
273
274{
275 struct sqlexd sqlstm;
276 sqlstm.sqlvsn = 10;
277 sqlstm.arrsiz = 4;
278 sqlstm.sqladtp = &sqladt;
279 sqlstm.sqltdsp = &sqltds;
280 sqlstm.iters = (unsigned int )10;
281 sqlstm.offset = (unsigned int )20;
282 sqlstm.cud = sqlcud0;
283 sqlstm.sqlest = (unsigned char *)&sqlca;
284 sqlstm.sqlety = (unsigned short)256;
285 sqlstm.occurs = (unsigned int )0;
286 sqlstm.sqhstv[0] = ( void *)&username;
287 sqlstm.sqhstl[0] = (unsigned int )22;
288 sqlstm.sqhsts[0] = ( int )22;
289 sqlstm.sqindv[0] = ( void *)0;
290 sqlstm.sqinds[0] = ( int )0;
291 sqlstm.sqharm[0] = (unsigned int )0;
292 sqlstm.sqadto[0] = (unsigned short )0;
293 sqlstm.sqtdso[0] = (unsigned short )0;
294 sqlstm.sqhstv[1] = ( void *)&password;
295 sqlstm.sqhstl[1] = (unsigned int )42;
296 sqlstm.sqhsts[1] = ( int )42;
297 sqlstm.sqindv[1] = ( void *)0;
298 sqlstm.sqinds[1] = ( int )0;
299 sqlstm.sqharm[1] = (unsigned int )0;
300 sqlstm.sqadto[1] = (unsigned short )0;
301 sqlstm.sqtdso[1] = (unsigned short )0;
302 sqlstm.sqphsv = sqlstm.sqhstv;
303 sqlstm.sqphsl = sqlstm.sqhstl;
304 sqlstm.sqphss = sqlstm.sqhsts;
305 sqlstm.sqpind = sqlstm.sqindv;
306 sqlstm.sqpins = sqlstm.sqinds;
307 sqlstm.sqparm = sqlstm.sqharm;
308 sqlstm.sqparc = sqlstm.sqharc;
309 sqlstm.sqpadto = sqlstm.sqadto;
310 sqlstm.sqptdso = sqlstm.sqtdso;
311 sqlcxt((void **)0, &sqlctx, &sqlstm, &sqlfpn);
312 if (sqlca.sqlcode < 0) sql_error("ORACLE error--\n");
313}
314
315
316
317 cout << "Connected to ORACLE as user: " << username.arr << endl;
318
319 /* Loop, asking for branch IDs */
320
321 do {
322
323 cout << "Enter branch number: (0 to quit) ";
324 cin >> temp_char;
325
326 if ( strcmp ( temp_char, "0" ) == 0 )
327 break; // stop the while loop
328
329 // Fill in branch_no that we will use in the query.
330 strncpy((char *) branch_no.arr, temp_char, 10);
331 branch_no.len = (unsigned short) strlen((char *) branch_no.arr);
332
333 /* Branch to the notfound label when the
334 * 1403 ("No data found") condition occurs.
335 * Although labels are required here, this does not mean that
336 * using labels in general is good programming practice!
337 * You are only allowed to use labels as target for an SQL GOTO statement.
338 */
339 /* EXEC SQL WHENEVER NOT FOUND GOTO notfound; */
340
341
342 /* EXEC SQL SELECT branch_no, address, phone, fax
343 INTO :branchrec
344 FROM Branch
345 WHERE branch_no = :branch_no; */
346
347{
348 struct sqlexd sqlstm;
349 sqlstm.sqlvsn = 10;
350 sqlstm.arrsiz = 5;
351 sqlstm.sqladtp = &sqladt;
352 sqlstm.sqltdsp = &sqltds;
353 sqlstm.stmt = "select branch_no ,address ,phone ,fax into :s1 ,:s2 ,:s3 \
354,:s4 from Branch where branch_no=:b1";
355 sqlstm.iters = (unsigned int )1;
356 sqlstm.offset = (unsigned int )51;
357 sqlstm.selerr = (unsigned short)1;
358 sqlstm.cud = sqlcud0;
359 sqlstm.sqlest = (unsigned char *)&sqlca;
360 sqlstm.sqlety = (unsigned short)256;
361 sqlstm.occurs = (unsigned int )0;
362 sqlstm.sqhstv[0] = ( void *)&branchrec.branch_no;
363 sqlstm.sqhstl[0] = (unsigned int )12;
364 sqlstm.sqhsts[0] = ( int )0;
365 sqlstm.sqindv[0] = ( void *)0;
366 sqlstm.sqinds[0] = ( int )0;
367 sqlstm.sqharm[0] = (unsigned int )0;
368 sqlstm.sqadto[0] = (unsigned short )0;
369 sqlstm.sqtdso[0] = (unsigned short )0;
370 sqlstm.sqhstv[1] = ( void *)&branchrec.address;
371 sqlstm.sqhstl[1] = (unsigned int )62;
372 sqlstm.sqhsts[1] = ( int )0;
373 sqlstm.sqindv[1] = ( void *)0;
374 sqlstm.sqinds[1] = ( int )0;
375 sqlstm.sqharm[1] = (unsigned int )0;
376 sqlstm.sqadto[1] = (unsigned short )0;
377 sqlstm.sqtdso[1] = (unsigned short )0;
378 sqlstm.sqhstv[2] = ( void *)&branchrec.phone;
379 sqlstm.sqhstl[2] = (unsigned int )15;
380 sqlstm.sqhsts[2] = ( int )0;
381 sqlstm.sqindv[2] = ( void *)0;
382 sqlstm.sqinds[2] = ( int )0;
383 sqlstm.sqharm[2] = (unsigned int )0;
384 sqlstm.sqadto[2] = (unsigned short )0;
385 sqlstm.sqtdso[2] = (unsigned short )0;
386 sqlstm.sqhstv[3] = ( void *)&branchrec.fax;
387 sqlstm.sqhstl[3] = (unsigned int )15;
388 sqlstm.sqhsts[3] = ( int )0;
389 sqlstm.sqindv[3] = ( void *)0;
390 sqlstm.sqinds[3] = ( int )0;
391 sqlstm.sqharm[3] = (unsigned int )0;
392 sqlstm.sqadto[3] = (unsigned short )0;
393 sqlstm.sqtdso[3] = (unsigned short )0;
394 sqlstm.sqhstv[4] = ( void *)&branch_no;
395 sqlstm.sqhstl[4] = (unsigned int )12;
396 sqlstm.sqhsts[4] = ( int )0;
397 sqlstm.sqindv[4] = ( void *)0;
398 sqlstm.sqinds[4] = ( int )0;
399 sqlstm.sqharm[4] = (unsigned int )0;
400 sqlstm.sqadto[4] = (unsigned short )0;
401 sqlstm.sqtdso[4] = (unsigned short )0;
402 sqlstm.sqphsv = sqlstm.sqhstv;
403 sqlstm.sqphsl = sqlstm.sqhstl;
404 sqlstm.sqphss = sqlstm.sqhsts;
405 sqlstm.sqpind = sqlstm.sqindv;
406 sqlstm.sqpins = sqlstm.sqinds;
407 sqlstm.sqparm = sqlstm.sqharm;
408 sqlstm.sqparc = sqlstm.sqharc;
409 sqlstm.sqpadto = sqlstm.sqadto;
410 sqlstm.sqptdso = sqlstm.sqtdso;
411 sqlcxt((void **)0, &sqlctx, &sqlstm, &sqlfpn);
412 if (sqlca.sqlcode == 1403) goto notfound;
413 if (sqlca.sqlcode < 0) sql_error("ORACLE error--\n");
414}
415
416
417
418 /* Print data.
419 * The branchrec.address VARCHAR is not \0 terminated. We have
420 * to make it \0 terminated first to print it.
421 */
422 branchrec.address.arr[branchrec.address.len] = '\0';
423 cout << "Address: " << branchrec.address.arr << endl;
424
425 branchrec.phone.arr[branchrec.phone.len] = '\0';
426 cout << "Phone: " << branchrec.phone.arr << endl;
427
428 branchrec.fax.arr[branchrec.fax.len] = '\0';
429 cout << "Fax: " << branchrec.fax.arr << endl;
430
431 // Continue the loop, the other lines in this loop are
432 // for error handling:
433 continue;
434
435notfound:
436 cout << endl << "Not a valid branch number - try again." << endl;
437
438 }
439 while ( true );
440 // continue after an invalid branch number.
441
442 // Disconnect from ORACLE.
443 /* EXEC SQL ROLLBACK WORK RELEASE; */
444
445{
446 struct sqlexd sqlstm;
447 sqlstm.sqlvsn = 10;
448 sqlstm.arrsiz = 5;
449 sqlstm.sqladtp = &sqladt;
450 sqlstm.sqltdsp = &sqltds;
451 sqlstm.iters = (unsigned int )1;
452 sqlstm.offset = (unsigned int )86;
453 sqlstm.cud = sqlcud0;
454 sqlstm.sqlest = (unsigned char *)&sqlca;
455 sqlstm.sqlety = (unsigned short)256;
456 sqlstm.occurs = (unsigned int )0;
457 sqlcxt((void **)0, &sqlctx, &sqlstm, &sqlfpn);
458 if (sqlca.sqlcode < 0) sql_error("ORACLE error--\n");
459}
460
461
462
463 exit(EXIT_SUCCESS);
464}
465
Note: See TracBrowser for help on using the repository browser.