Skip to Main Content

OCI - How to bind an array of structure with string member to input parameters of stored procedure?

JingCApr 22 2022

I can get binding an array of numbers as input parameters working. But when I tried to applied similar concept for binding an array of structure with string member, it has segmentation fault during execute. Can someone please either provide a sample code or point me to the correct direction?
Here's the portion of my code that tried to bind the array of structure:
typedef OCIRef T_OBJ_ORDR_ATTR_ref;
typedef OCIArray T_ARRAY_ORDR_ATTR;
struct T_OBJ_ORDR_ATTR
{
OCINumber code;
OCIString * value;
};
typedef struct T_OBJ_ORDR_ATTR T_OBJ_ORDR_ATTR;
struct T_OBJ_ORDR_ATTR_ind
{
OCIInd _atomic;
OCIInd code;
OCIInd value;
};
typedef struct T_OBJ_ORDR_ATTR_ind T_OBJ_ORDR_ATTR_ind;
OCIArray *array_param = NULL;
std::vector<T_OBJ_ORDR_ATTR*> eleArray = {NULL, NULL, NULL};

//----- REGISTER TYPE INFORMATION ------------------------------------------------------

// This section can be invoked once per session to minimize server roundtrips.

OCIType *type_tdo = NULL;
OCIType *ele_type_tdo = NULL;
char *type_owner_name = "W561869";
// char *type_name = "T_ARRAY_EH_DEP";
char *type_name = "T_ARRAY_ORDR_ATTR";
char *ele_type_name = "T_OBJ_ORDR_ATTR";
//sword rc;
rc= OCITypeByName( myenvhp, myerrhp, mysvchp,
(CONST text *)type_owner_name, strlen(type_owner_name),
(CONST text *) type_name, strlen(type_name),
NULL, 0,
OCI_DURATION_SESSION, OCI_TYPEGET_HEADER,
&type_tdo
);
if( check_oci_error("OCITypeByName()", myerrhp, rc, myenvhp) ) return -1;

rc= OCITypeByName( myenvhp, myerrhp, mysvchp,
(CONST text *)type_owner_name, strlen(type_owner_name),
(CONST text *) ele_type_name, strlen(ele_type_name),
NULL, 0,
OCI_DURATION_SESSION, OCI_TYPEGET_HEADER,
&ele_type_tdo
);
if( check_oci_error("OCITypeByName() ele", myerrhp, rc, myenvhp) ) return -1;

//----- PREPARE PARAMETER INSTANCE ---------------------------------------------

rc = OCIObjectNew(
myenvhp, myerrhp, mysvchp,
OCI_TYPECODE_VARRAY,
type_tdo, NULL, OCI_DURATION_SESSION, TRUE,
(void**) &array_param
);
if( check_oci_error("OCIObjectNew()", myerrhp, rc, myenvhp) ) return -1;
//----- FILL PARAMETER ---------------------------------------------------------

OCINumber num_val;
int int_val=0;
std::stringstream ss;
for(int i = 0; i < eleArray.size(); ++i) {
rc = OCIObjectNew(
myenvhp, myerrhp, mysvchp,
OCI_TYPECODE_OBJECT,
ele_type_tdo, NULL, OCI_DURATION_SESSION, TRUE,
(void**) &(eleArray[i])
);
if( check_oci_error("OCIObjectNew() ele", myerrhp, rc, myenvhp) ) return -1;

int\_val += 1 ;  
ss \<\< "value" \<\< int\_val;  
text \* strVal = (text\*)ss.str().c\_str();  
ss.str("");  
ub4 strLen = (ub4)(strlen((char \*) strVal));  

rc = OCINumberFromInt(myerrhp, &int\_val, sizeof(int\_val), OCI\_NUMBER\_SIGNED, &(eleArray\[i\]->code));  
if( check\_oci\_error("OCINumberFromInt()", myerrhp, rc, myenvhp) ) return -1;  
rc = OCIStringAssignText(myenvhp, myerrhp, strVal, strLen, &(eleArray\[i\]->value));  
if( check\_oci\_error("OCIStringAssignText()", myerrhp, rc, myenvhp) ) return -1;  

//cout \<\< "code:" \<\< eleArray\[i\]->code \<\< " value:" \<\< eleArray\[i\]->value \<\< endl;  

rc = OCICollAppend(myenvhp, myerrhp, eleArray\[i\], NULL, array\_param);  
if( check\_oci\_error("OCICollAppend()", myerrhp, rc, myenvhp) ) return -1;  

}

OCIIter *varray_iterator;
rc = OCIIterCreate(myenvhp, myerrhp, (CONST OCIColl*) array_param, &varray_iterator);
if( check_oci_error("OCIIterCreate()", myerrhp, rc, myenvhp) ) return -1;
T_OBJ_ORDR_ATTR * attr = NULL;
T_OBJ_ORDR_ATTR_ind * attrInd = NULL;
boolean endOfCollection = FALSE;
while ((OCIIterNext(
myenvhp, myerrhp, varray_iterator, (void**)&attr, (void**)&attrInd, &endOfCollection) == OCI_SUCCESS) &&
!endOfCollection) {
printf("value: %s \n", OCIStringPtr(myenvhp, (*attr).value));
}

// OCIBind *bndp = NULL;

rc = OCIBindByPos(
mystmthp, &bndp, myerrhp,
(ub4) 7,
NULL, 0,
SQLT_NTY, NULL, 0, 0, 0, 0,
OCI_DEFAULT
);
if( check_oci_error("OCIBindByPos() 7", myerrhp, rc, myenvhp) ) return -1;

rc = OCIBindObject(
bndp, myerrhp,
type_tdo, (dvoid **) array_param,
NULL, NULL, NULL
);
if( check_oci_error("OCIBindObject()", myerrhp, rc, myenvhp) ) return -1;

-----------------------------------------------------------------------------------------
The debug code does print out the structure ok:
value: value1
value: value2
value: value3
Segmentation fault (core dumped)

Comments
Post Details
Added on Apr 22 2022
0 comments
6 views