【问题标题】:Try to get blob data from Oracle by OCI routines but get error: ORA-01008: not all variables bound尝试通过 OCI 例程从 Oracle 获取 blob 数据,但出现错误:ORA-01008: not all variables bound
【发布时间】:2020-06-08 06:55:27
【问题描述】:

我尝试通过 OCI 例程从 Oracle 获取 blob 数据。 我使用下一个代码,但执行语句给出了错误:ORA-01008: not all variables bound 我错了什么?有谁能够帮我? 谢谢, 基斯布拉克斯马

void get_blob_data()
{
// The query
// The results of this methode 
// if errstring is empty, the blob data can be found in the 4th parameter.
// otherwise the error is given in errstring
CString csQuery;
csQuery.Format("BEGIN get_blob('%s','%ld',:ERRSTRING,:BLOB); END;", "20", 200);

//init
OCIHandleAlloc((dvoid *)m_OCIEnvironment , (dvoid **)(&m_OCIStatement),
    (ub4)OCI_HTYPE_STMT, (size_t)0, (dvoid **)0);

//Prepare statement voor query
OCIStmtPrepare(m_OCIStatement, m_OCIError, (text *)(csQuery),
    (ub4)(strlen(csQuery)), (ub4)OCI_NTV_SYNTAX, (ub4)OCI_DEFAULT);

// output variables
char *pszResult = (char*)malloc(256);
memset(pszResult, 0, sizeof(pszResult));
Blob *blob = new Blob();

m_pIndicator1 = malloc(sizeof(OCIInd));
m_pDefine1 = NULL;

OCIDefineByPos(m_OCIStatement, &m_pDefine1, m_OCIError, (ub4)1,
    (dvoid*)*pszResult,
    (sb4)256, SQLT_STR,
    (dvoid*)m_pIndicator1,
    (ub2*)0, (ub2*)0, (ub4)OCI_DEFAULT);

m_pIndicator2 = malloc(sizeof(OCIInd));
m_pDefine2 = NULL;
OCIDescriptorAlloc(m_OCIEnvironment, &blob, (ub4)OCI_DTYPE_LOB, (size_t)0, (dvoid **)0);

OCIDefineByPos(m_OCIStatement, &m_pDefine2,
    m_OCIError, (ub4)2,
    (dvoid*)blob,
    (sb4)-1, SQLT_BLOB,
    (dvoid*)m_pIndicator2,
    (ub2*)0, (ub2*)0, (ub4)OCI_DEFAULT));


iStatus = OCIStmtExecute(m_OCISrvCtx, m_OCIStatement, m_OCIError, (ub4)1, (ub4)0, 
    (OCISnapshot *)NULL, (OCISnapshot *)NULL, 
    (ub4)OCI_DEFAULT);

// results:
// iStatus = -1;
// Errorstring: ORA-01008: not all variables bound
}

【问题讨论】:

    标签: c++ oracle blob oracle-call-interface


    【解决方案1】:

    您没有任何 OCIBindByName() 调用。 OCIDefineByPos() 在运行 SQL 查询时使用,而您不是。

    在 PL/SQL 调用中混合使用 %s 和绑定变量很奇怪。我认为您想对所有参数使用绑定变量。

    一个方便的提示是查看ODPI-C 如何使用 OCI。对于 LOB,您可以直接获取定位器或数据。后者要快很多,但仅限于 1G。可以说安装 Python 和 cx_Oracle 并运行一些示例是最简单的,例如ReturnLobsAsStrings.py。您可以在 dpiOci.c 中跟踪 OCI 调用。

    有一些示例 OCI 程序(遗憾的是不太容易访问 - 您的 DBA 可能能够安装它们),请注意 cdemolb.c 和 cdemolbs.c

    【讨论】:

    • 您好克里斯托弗,感谢您的回答!我使用的是OCIDefineBypos(),因为这两个参数是输出参数。对不起,我忘了提!基斯
    • 使用 OCIDefine* 进行查询,而不是执行 PL/SQL 代码。您需要使用 OCIBindByPos 或类似的。
    【解决方案2】:

    最佳 Oracle 用户,

    从 Oracle 获取 blob 仍然存在问题。我用的太少了。 大多数情况下,我复制一些代码并且新查询工作正常。

    我要求我的同事更改功能。 新的查询是:


    从双重选择 ngm_transactie_pck.get_checkout_blob('20','200')

    这个函数的结果是一个blob。 所以我编程了:

    静态OCILobLocator *blob = NULL; 在 OCIHandleAlloc() 和 OCIStmtPrepare() 之后,就像前面的例子一样,我有:

    OCIDescriptorAlloc(m_OCIEnvironment, &blob, (ub4)OCI_DTYPE_LOB, (size_t)0, (dvoid **)0);

    CIDefineByPos(m_OCIStatement, &m_pDefine2, m_OCIError, (ub4)1, (dvoid*)&blob, (sb4)-1,OCI_DTYPE_LOB, (dvoid*)m_pIndicator2, (ub2*)0, (ub2*)0, (ub4)OCI_DEFAULT));

    对 OciDefineByPos() 的调用会导致崩溃/堆栈溢出。 我错了什么? 问候, 凯斯

    【讨论】:

    • 请更新您的原始问题或发布新问题,而不是“回答”第二个问题。
    猜你喜欢
    • 1970-01-01
    • 2014-01-08
    • 2016-08-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-10-25
    • 1970-01-01
    相关资源
    最近更新 更多