Re: using host arrays in PRO*C
Date: 1995/08/16
Message-ID: <40r6hs$3fc_at_inet-nntp-gw-1.us.oracle.com>#1/1
sber_at_netcom.com (Shneor Berezin) wrote:
>I wonder how the dimension of host arrays in PRO*C is determined by Oracle.
>Looking at the generated C code, only the address of the array is being
>passed to sqlcex.
You didn't look very closely then.
>The dummy at Oracle technical support told me, that this is proprietary
>information and I don't need to know. Unbelievable!!!
They are right you know. Firstly, it may be passed in a variety of ways, depending on the circumstance. Secondly, it may change from version to version. Third, unless you snoop the code, it isn't documented. Undocumented things are 'proprietary'.
>Personally, I don't know of any reliable way of determining the size of
>an array allocated on the heap. Has anybody tried to use a host array
Thats because you are using C. In the Language C is it up to YOU the programmer to keep track of such things. C is close to assembler, C is not close to Ada (in which case you would just use a ' (tick) function). There ISN'T any reliable OR unreliable way to tell the size of an array on the heap.
>allocated on the heap? Would it help if I use a FOR clause?
Yes it would.
To see why I said you didn't look very closely at the generated code, consider the following small example:
In proc*c:
EXEC SQL BEGIN DECLARE SECTION;
int empno[100]; int * empno_dyn; EXEC SQL END DECLARE SECTION; int n = 100;
empno_dyn = (int *) malloc( n * sizeof(int) );
EXEC SQL DECLARE C1 CURSOR FOR SELECT EMPNO FROM EMP;
EXEC SQL OPEN C1;
EXEC SQL FETCH C1 INTO :empno; /* WILL FETCH UPTO 100 rows */
EXEC SQL FETCH C1 INTO :empno_dyn; /* WILL FETCH *** 1 *** row at most */
EXEC SQL FOR :n FETCH C1 INTO :empno_dyn; /* WILL FETCH UPTO *** N *** rows*/
EXEC SQL CLOSE C1;
......
If you looked at the generated code for this you would see:
#line 88 "template.pc"
/* EXEC SQL FETCH C1 into :empno; */
#line 89 "template.pc"
{
sqlstm.iters = (unsigned int )100; ^^^^^^^ Pretty much says 100.........
#line 89 "template.pc"
/* EXEC SQL FETCH C1 into :empno_dyn; */
#line 90 "template.pc"
{
sqlstm.iters = (unsigned int )1; ^^^^^^ Pretty much says 1..........
#line 90 "template.pc"
/* EXEC SQL FOR :n FETCH C1 into :empno_dyn; */
#line 91 "template.pc"
{
sqlstm.iters = (unsigned int )n; ^^^^^^ Pretty much says n ................
To sum it up, the following (with array sizes of 5) prints out the first 11 empnos from scott.emp. Unless you tell PRO*C the size of a dynamically allocated array, it has no idea.
EXEC SQL BEGIN DECLARE SECTION;
int empno[5]; int * empno_dyn; int n = 5; int i; int cnt;
EXEC SQL END DECLARE SECTION; EXEC SQL DECLARE C1 CURSOR FOR SELECT EMPNO FROM EMP; empno_dyn = (int *)malloc( n*sizeof(int) ); EXEC SQL OPEN C1;
EXEC SQL FETCH C1 into :empno; /* PRINTS 5 rows */ cnt = sqlca.sqlerrd[2];
for( i = 0; i < cnt; i++ )
printf( "%d\n", empno[i] );
EXEC SQL FETCH C1 into :empno_dyn; /* PRINTS 1 row */ for( i = 0; i < sqlca.sqlerrd[2]-cnt; i++ )
printf( "%d\n", empno_dyn[i] );
cnt = sqlca.sqlerrd[2];
EXEC SQL FOR :n FETCH C1 into :empno_dyn; /* PRINTS 5 rows */ for( i = 0; i < sqlca.sqlerrd[2]-cnt; i++ )
printf( "%d\n", empno_dyn[i] );
EXEC SQL CLOSE C1;
>Thanks,
>Shneor Berezin, SMTS, Molecular Simulations Inc., shneor_at_ba.msi.com
Thomas Kyte
tkyte_at_us.oracle.com
Oracle Government
Received on Wed Aug 16 1995 - 00:00:00 CEST