| Oracle FAQ | Your Portal to the Oracle Knowledge Grid | |
Home -> Community -> Usenet -> c.d.o.misc -> How to bind a collection in OCI?
I would like to convert the following PL/SQL procedure to C. This procedure
works properly and displays
SQL> exec testcollection;
value: 2 value: 3 value: 5
CREATE OR REPLACE TYPE testval_type AS OBJECT (
        value NUMBER
);
/
show errors;
CREATE OR REPLACE TYPE testval_table
        AS table of testval_type;
/
show errors;
CREATE OR REPLACE PROCEDURE TestCollection IS
	TYPE resCur IS REF CURSOR;
	crs		 resCur;
	stmt      varchar2(1000);
	vvalue    number;
	vTestList testval_table;
BEGIN --TestCollection
	vTestList := testval_table();
	vTestList.extend(1);
	vTestList(1) := testval_type(2);
	vTestList.extend(1);
	vTestList(2) := testval_type(3);
	vTestList.extend(1);
	vTestList(3) := testval_type(5);
	stmt := 'SELECT value FROM TABLE(CAST(:1 as testval_table))';
	open crs for stmt using vTestList;
	loop	
		fetch crs into vvalue; 
		exit when crs%notfound;
		dbms_output.put_line('value: ' || vvalue);
	end loop;
	close crs;
END TestCollection;
/
show errors;
/
exec testcollection;
So far for the PL/SQL version. The equivalent OCI program looks like this (it runs without any error, but for some strange reason OCIStmtFetch() always returns 100 (OCI_NO_DATA) as result, and not the numbers I've fed into the collection. I guess that my collection somehow didn't make it to Oracle (I'm using Oracle 9.2) - perhaps because of some missing or incorrect bind call? - and Oracle thinks the collection is empty (although OCITableSize() reports that my collection has a size > 0).
static text *sel1int = (text *)"SELECT value FROM TABLE(CAST(:1 as testval_table))";
   OCIStmt *sel1stmthp;
   OCINumber sel1val_num;
   OCIType *ttab_tdo = (OCIType *) 0;
   OCIArray *ttab_obj = NULL;
   OCIInd *ind = NULL;
   boolean exist = FALSE;
   sword result;
   sb4 tabsize;
   OCINumber testval;
   unsigned int value;
result = OCIHandleAlloc( (dvoid *) gctx->envhp,
                           (dvoid **) &sctx->sel1stmthp,
                           OCI_HTYPE_STMT, (size_t) 0, (dvoid **) 0);
   if (result != OCI_SUCCESS)
      printf("error\n");
   result = OCIStmtPrepare(sctx->sel1stmthp, 
                           gctx->errhp, (text *)sel1int,
                           (ub4) strlen((char *)sel1int),
                           (ub4) OCI_NTV_SYNTAX, 
                           (ub4) OCI_DEFAULT);
   if (result != OCI_SUCCESS)
      printf("error\n");
   /* bind the variables */
   result = OCIDefineByPos(sctx->sel1stmthp, 
                           &sel1def1p, gctx->errhp, 1, 
                           (dvoid *) &sel1val_num,
                           (sb4) sizeof(unsigned char[22]), 
                           SQLT_VNU, (dvoid *) 0, (ub2 *)0,
                           (ub2 *)0, OCI_DEFAULT);
   if (result != OCI_SUCCESS)
      printf("error\n");
   result = OCIBindByPos(sctx->sel1stmthp, 
                        &sel1bnd1p, gctx->errhp, 1, 
                        (dvoid *) 0, (sb4) 0, SQLT_NTY,
                        (dvoid *) 0, (ub2 *) 0, (ub2 *) 0, 
                        (ub4) 0, (ub4 *) 0, OCI_DEFAULT);
   if (result != OCI_SUCCESS)
      printf("error\n");
   result = OCITypeByName(gctx->envhp, gctx->errhp, 
                        gctx->svchp, (const text *) 0, (ub4) 0, 
                        (const text *) "TESTVAL_TABLE", 
                        (ub4) strlen((const char *) "TESTVAL_TABLE"),
                        (CONST text *) 0, (ub4) 0, 
                        OCI_DURATION_SESSION, OCI_TYPEGET_HEADER, 
                        &ttab_tdo);
   if (result != OCI_SUCCESS)
      printf("error\n");
   result = OCIObjectNew(gctx->envhp, gctx->errhp, 
                        gctx->svchp, OCI_TYPECODE_VARRAY, 
                        (OCIType *) ttab_tdo, (dvoid *) 0, 
                        OCI_DURATION_SESSION, (ub1) TRUE, 
                        (dvoid **) &ttab_obj);
   if (result != OCI_SUCCESS)
      printf("error\n");
   result = OCIBindObject(sel1bnd1p, gctx->errhp, 
                        ttab_tdo, (dvoid **) &ttab_obj, 
                        (ub4 *) 0, (dvoid **) &ind, (ub4 *) 0);
   if (result != OCI_SUCCESS)
      printf("error\n");
// assign some values to the collection
   value = 2;
   result = OCINumberFromInt(gctx->errhp, (dvoid *) &value,
                              sizeof(unsigned int), OCI_NUMBER_SIGNED, 
                              (struct OCINumber *) &testval);
   if (result != OCI_SUCCESS)
      printf("error\n");
   result = OCICollAppend(gctx->envhp, gctx->errhp,
                           (CONST dvoid*) &testval, (CONST dvoid*) NULL, 
                           (OCIColl *) ttab_obj);
   if (result != OCI_SUCCESS)
      printf("error\n");
   value = 3;
   result = OCINumberFromInt(gctx->errhp, (dvoid *) &value,
                              sizeof(unsigned int), OCI_NUMBER_SIGNED, 
                              (struct OCINumber *) &testval);
   if (result != OCI_SUCCESS)
      printf("error\n");
   result = OCICollAppend(gctx->envhp, gctx->errhp,
                           (CONST dvoid*) &testval, (CONST dvoid*) NULL, 
                           (OCIColl *) ttab_obj);
   if (result != OCI_SUCCESS)
      printf("error\n");
   value = 5;
   result = OCINumberFromInt(gctx->errhp, (dvoid *) &value,
                              sizeof(unsigned int), OCI_NUMBER_SIGNED, 
                              (struct OCINumber *) &testval);
   if (result != OCI_SUCCESS)
      printf("error\n");
   result = OCICollAppend(gctx->envhp, gctx->errhp,
                           (CONST dvoid*) &testval, (CONST dvoid*) NULL, 
                           (OCIColl *) ttab_obj);
   if (result != OCI_SUCCESS)
      printf("error\n");
// OCITableSize (only called for testing purposes) returns 3
result = OCITableSize(gctx->envhp, gctx->errhp,
                           (CONST OCITable*) ttab_obj, &tabsize);
   if (result != OCI_SUCCESS)
printf("error\n");
result = OCIStmtExecute(gctx->svchp, sctx->sel1stmthp,
                           gctx->errhp, (ub4) 0, (ub4) 0,
                           (CONST OCISnapshot *) NULL, 
                           (OCISnapshot *) NULL, OCI_DEFAULT );
   if (result != OCI_SUCCESS)
      printf("error\n");
// this function always returns OCI_NO_DATA as result, // can somebody please tell me what I'm doing wrong?
result = OCIStmtFetch(sctx->sel1stmthp, gctx->errhp,
                        (ub4) 1, OCI_FETCH_NEXT, OCI_DEFAULT);
Thanks in advance,
Danny. Received on Tue Apr 06 2004 - 02:11:58 CDT
![]()  | 
![]()  |