Re: using host arrays in PRO*C

From: Thomas J Kyte <tkyte_at_us.oracle.com>
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

Original text of this message