Forum Stats

  • 3,838,603 Users
  • 2,262,384 Discussions
  • 7,900,692 Comments

Discussions

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

JingC
JingC Member Posts: 1 Green Ribbon

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)

Tagged: