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

Last change on this file since 351 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
Line 
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.