Oracle11g OCI-21560 OCI对象新OCI_类型代码_表

Oracle11g OCI-21560 OCI对象新OCI_类型代码_表,oracle11g,oracle-call-interface,instantclient,Oracle11g,Oracle Call Interface,Instantclient,我被这个问题困扰了一段时间。我浏览了大量关于这方面的代码/示例和文档(虽然不多) 我试图做的是:使用C中的OCI,通过过程IN/OUT参数读取和写入PL/SQL表 Oracle软件包的定义如下: DROP PACKAGE pkg_test; DROP TYPE ARRRECNR; DROP TYPE ARRRECDATA; CREATE OR REPLACE TYPE ARRRECNR IS TABLE OF NUMBER(8); / CREATE OR REPLACE TYPE ARRREC

我被这个问题困扰了一段时间。我浏览了大量关于这方面的代码/示例和文档(虽然不多)

我试图做的是:使用C中的OCI,通过过程IN/OUT参数读取和写入PL/SQL表

Oracle软件包的定义如下:

DROP PACKAGE pkg_test;
DROP TYPE ARRRECNR;
DROP TYPE ARRRECDATA;

CREATE OR REPLACE TYPE ARRRECNR IS TABLE OF NUMBER(8);
/
CREATE OR REPLACE TYPE ARRRECDATA IS TABLE OF VARCHAR2(4000);
/

CREATE OR REPLACE PACKAGE pkg_test
IS
    PROCEDURE test_proc1 (
      p_RecordNr In ARRRECNR,
      p_RecordData In ARRRECDATA,
      p_RecCount OUT Number,
      p_outrecorddata OUT ARRRECDATA
    );
END;
/

CREATE OR REPLACE PACKAGE BODY pkg_test
IS
   PROCEDURE test_proc1 (
      p_RecordNr In ARRRECNR,
      p_RecordData In ARRRECDATA,
      p_RecCount OUT Number,
      p_OutRecordData OUT ARRRECDATA
  ) IS
BEGIN
    p_RecCount = 0;
    p_OutRecordData := ARRRECDATA();
   FOR I IN 1..p_RecordData.COUNT
   LOOP
      p_OutRecordData.extend();
      p_OutRecordData(I) := p_RecordData(I) || ' ' || to_char(p_RecordNr(I));
      p_RecCount := p_RecCount + I;
    END LOOP;
END test_proc1;

END pkg_test;
/
status = OCIStmtPrepare2(..., &stmthp,...
                         NULL /*const OraText *key*/,
                         0 /*ub4 keylen*/,
                         OCI_NTV_SYNTAX,
                         OCI_DEFAULT);

if (status != OCI_SUCCESS) { return -1; }

OCIBind *bindpp_P_RECCOUNT = NULL;
sword P_RECCOUNT = 0;
status = OCIBindByName(stmthp, &bindpp_P_RECCOUNT, errhp,
            (text *)":P_RECCOUNT", strlen(":P_RECCOUNT"),
            (ub1 *)&P_RECCOUNT, (sword)sizeof(P_RECCOUNT),
            SQLT_INT, (dvoid *)0, (ub2 *)0, (ub2)0, (ub4)0, (ub4 *)0,
            OCI_DEFAULT);
if (status != OCI_SUCCESS) { return -1; }

OCIBind *bindpp_P_RECORDNR = NULL;
status = OCIBindByName(stmthp, &bindpp_P_RECORDNR, errhp, (text *)":P_RECORDNR",
                     -1, NULL /*void *valuep*/,
                     (sb4)sizeof(OCITable *) /*sb4 value_sz*/,
                     SQLT_NTY /*ub2 dty*/,
                      NULL /*void *indp*/,
                      NULL /*ub2 *alenp*/,
                      NULL /*ub2 *rcodep*/,
                      0 /*ub4 maxarr_len*/,
                      NULL /*ub4 *curelep*/,
                     OCI_DEFAULT /*ub4 mode*/);
if (status != OCI_SUCCESS) { return -1; }

OCIBind *bindpp_P_RECORDDATA = NULL;
status = OCIBindByName(stmthp, &bindpp_P_RECORDDATA, errhp, ":P_RECORDDATA", (sb4)-1,
                      NULL /*void *valuep*/, (sb4)sizeof(OCITable *) /*sb4 value_sz*/,
                     SQLT_NTY /*ub2 dty*/, NULL /*void *indp*/, NULL /*ub2 *alenp*/,
                      NULL /*ub2 *rcodep*/, 0 /*ub4 maxarr_len*/, NULL /*ub4 *curelep*/,
                     OCI_DEFAULT /*ub4 mode*/);
if (status != OCI_SUCCESS) { return -1; }

OCIBind *bindpp_P_OUTRECORDDATA = NULL;
status = OCIBindByName(stmthp, &bindpp_P_OUTRECORDDATA, errhp, ":P_OUTRECORDDATA",(sb4)-1,
                      NULL /*void *valuep*/,(sb4)sizeof(OCITable *) /*sb4 value_sz*/,
                     SQLT_NTY /*ub2 dty*/,
                      NULL /*void *indp*/, NULL /*ub2 *alenp*/, NULL /*ub2 *rcodep*/,
                      0 /*ub4 maxarr_len*/, NULL /*ub4 *curelep*/, OCI_DEFAULT /*ub4 mode*/);
if (status != OCI_SUCCESS) { return -1; }

OCIType *ArrRecNr = NULL;
status = OCITypeByName(envhp, errhp, svchp, NULL, 0,
                      "ARRRECNR", (ub4)strlen("ARRRECNR"),
                      NULL, 0, OCI_DURATION_SESSION,
                     OCI_TYPEGET_ALL, &ArrRecNr);
if (status != OCI_SUCCESS || !ArrRecNr) { return -1; }


OCIType *ArrRecData = NULL;
status = OCITypeByName(envhp, errhp, svchp, NULL, 0,
                      "ARRRECDATA", (ub4)strlen("ARRRECDATA"),
                      NULL, 0, OCI_DURATION_SESSION,
                     OCI_TYPEGET_ALL, &ArrRecData);
if (status != OCI_SUCCESS || !ArrRecData) { return -1; }

OCITable *in_P_RECORDNR = NULL;
status = OCIObjectNew(envhp, errhp, svchp,
                     OCI_TYPECODE_TABLE, bindpp_P_RECORDNR,
                      NULL, OCI_DURATION_SESSION,
                      TRUE, &in_P_RECORDNR);

if (status != OCI_SUCCESS)
{
    printf("\nOCIObjectNew(envhp %p, errhp %p, svchp %p,\n"
      "OCI_TYPECODE_TABLE %d, bindpp_P_RECORDNR %p\n"
      "NULL %p, OCI_DURATION_SESSION %d\n"
      "TRUE %d, &in_P_RECORDNR %p)\n",
     envhp, errhp, svchp,
     OCI_TYPECODE_TABLE, bindpp_P_RECORDNR,
      NULL, OCI_DURATION_SESSION,
      TRUE, &in_P_RECORDNR);
    return -1;
}
现在我尝试调用以下PL/SQL:

BEGIN
    pkg_test.test_proc1 (
        P_RECORDNR => :P_RECORDNR,
        P_RECORDDATA => :P_RECORDDATA,
        P_RECCOUNT => :P_RECCOUNT,
        P_OUTRECORDDATA => :P_OUTRECORDDATA
    );
END
/
C(OCI)的调用如下所示:

DROP PACKAGE pkg_test;
DROP TYPE ARRRECNR;
DROP TYPE ARRRECDATA;

CREATE OR REPLACE TYPE ARRRECNR IS TABLE OF NUMBER(8);
/
CREATE OR REPLACE TYPE ARRRECDATA IS TABLE OF VARCHAR2(4000);
/

CREATE OR REPLACE PACKAGE pkg_test
IS
    PROCEDURE test_proc1 (
      p_RecordNr In ARRRECNR,
      p_RecordData In ARRRECDATA,
      p_RecCount OUT Number,
      p_outrecorddata OUT ARRRECDATA
    );
END;
/

CREATE OR REPLACE PACKAGE BODY pkg_test
IS
   PROCEDURE test_proc1 (
      p_RecordNr In ARRRECNR,
      p_RecordData In ARRRECDATA,
      p_RecCount OUT Number,
      p_OutRecordData OUT ARRRECDATA
  ) IS
BEGIN
    p_RecCount = 0;
    p_OutRecordData := ARRRECDATA();
   FOR I IN 1..p_RecordData.COUNT
   LOOP
      p_OutRecordData.extend();
      p_OutRecordData(I) := p_RecordData(I) || ' ' || to_char(p_RecordNr(I));
      p_RecCount := p_RecCount + I;
    END LOOP;
END test_proc1;

END pkg_test;
/
status = OCIStmtPrepare2(..., &stmthp,...
                         NULL /*const OraText *key*/,
                         0 /*ub4 keylen*/,
                         OCI_NTV_SYNTAX,
                         OCI_DEFAULT);

if (status != OCI_SUCCESS) { return -1; }

OCIBind *bindpp_P_RECCOUNT = NULL;
sword P_RECCOUNT = 0;
status = OCIBindByName(stmthp, &bindpp_P_RECCOUNT, errhp,
            (text *)":P_RECCOUNT", strlen(":P_RECCOUNT"),
            (ub1 *)&P_RECCOUNT, (sword)sizeof(P_RECCOUNT),
            SQLT_INT, (dvoid *)0, (ub2 *)0, (ub2)0, (ub4)0, (ub4 *)0,
            OCI_DEFAULT);
if (status != OCI_SUCCESS) { return -1; }

OCIBind *bindpp_P_RECORDNR = NULL;
status = OCIBindByName(stmthp, &bindpp_P_RECORDNR, errhp, (text *)":P_RECORDNR",
                     -1, NULL /*void *valuep*/,
                     (sb4)sizeof(OCITable *) /*sb4 value_sz*/,
                     SQLT_NTY /*ub2 dty*/,
                      NULL /*void *indp*/,
                      NULL /*ub2 *alenp*/,
                      NULL /*ub2 *rcodep*/,
                      0 /*ub4 maxarr_len*/,
                      NULL /*ub4 *curelep*/,
                     OCI_DEFAULT /*ub4 mode*/);
if (status != OCI_SUCCESS) { return -1; }

OCIBind *bindpp_P_RECORDDATA = NULL;
status = OCIBindByName(stmthp, &bindpp_P_RECORDDATA, errhp, ":P_RECORDDATA", (sb4)-1,
                      NULL /*void *valuep*/, (sb4)sizeof(OCITable *) /*sb4 value_sz*/,
                     SQLT_NTY /*ub2 dty*/, NULL /*void *indp*/, NULL /*ub2 *alenp*/,
                      NULL /*ub2 *rcodep*/, 0 /*ub4 maxarr_len*/, NULL /*ub4 *curelep*/,
                     OCI_DEFAULT /*ub4 mode*/);
if (status != OCI_SUCCESS) { return -1; }

OCIBind *bindpp_P_OUTRECORDDATA = NULL;
status = OCIBindByName(stmthp, &bindpp_P_OUTRECORDDATA, errhp, ":P_OUTRECORDDATA",(sb4)-1,
                      NULL /*void *valuep*/,(sb4)sizeof(OCITable *) /*sb4 value_sz*/,
                     SQLT_NTY /*ub2 dty*/,
                      NULL /*void *indp*/, NULL /*ub2 *alenp*/, NULL /*ub2 *rcodep*/,
                      0 /*ub4 maxarr_len*/, NULL /*ub4 *curelep*/, OCI_DEFAULT /*ub4 mode*/);
if (status != OCI_SUCCESS) { return -1; }

OCIType *ArrRecNr = NULL;
status = OCITypeByName(envhp, errhp, svchp, NULL, 0,
                      "ARRRECNR", (ub4)strlen("ARRRECNR"),
                      NULL, 0, OCI_DURATION_SESSION,
                     OCI_TYPEGET_ALL, &ArrRecNr);
if (status != OCI_SUCCESS || !ArrRecNr) { return -1; }


OCIType *ArrRecData = NULL;
status = OCITypeByName(envhp, errhp, svchp, NULL, 0,
                      "ARRRECDATA", (ub4)strlen("ARRRECDATA"),
                      NULL, 0, OCI_DURATION_SESSION,
                     OCI_TYPEGET_ALL, &ArrRecData);
if (status != OCI_SUCCESS || !ArrRecData) { return -1; }

OCITable *in_P_RECORDNR = NULL;
status = OCIObjectNew(envhp, errhp, svchp,
                     OCI_TYPECODE_TABLE, bindpp_P_RECORDNR,
                      NULL, OCI_DURATION_SESSION,
                      TRUE, &in_P_RECORDNR);

if (status != OCI_SUCCESS)
{
    printf("\nOCIObjectNew(envhp %p, errhp %p, svchp %p,\n"
      "OCI_TYPECODE_TABLE %d, bindpp_P_RECORDNR %p\n"
      "NULL %p, OCI_DURATION_SESSION %d\n"
      "TRUE %d, &in_P_RECORDNR %p)\n",
     envhp, errhp, svchp,
     OCI_TYPECODE_TABLE, bindpp_P_RECORDNR,
      NULL, OCI_DURATION_SESSION,
      TRUE, &in_P_RECORDNR);
    return -1;
}

这在尝试使用BindByName时给了我以下错误:

 OCI-21560: argument 4 is null, invalid, or out of range
服务器

客户端

我检查了所有输入参数,第四个参数不为空:

OCIObjectNew(
    envhp 0000027D223CE9B0,
    errhp 0000027D223FC590,
    svchp 0000027D223FB808,
    OCI_TYPECODE_TABLE 248,
    bindpp_P_RECORDNR 0000027D23D6B1B0,
    NULL 0000000000000000,
    OCI_DURATION_SESSION 10,
    TRUE 1,
    &in_P_RECORDNR 000000BCD47FFE00
)
我错过了什么