OCIStmtPrepare返回OCI_INVALID_HANDLE

时间:2017-01-22 10:04:56

标签: c oracle oracle-pro-c

我使用下面的代码INSERT到oracle表中。插入查询包含ÜÜ个字符。

当我呼叫OCI_INVALID_HANDLE时,我收到OCIStmtPrepare错误。这可能是什么问题?

int executeINSERTQuery()
{
    OCIEnv *envhp;
    OCIError *errhp = NULL;
    OCISvcCtx *svchp = NULL;
    OCIExtProcContext *context=NULL;
    int status = OCIEnvNlsCreate((OCIEnv **)&envhp,
                                (ub4)0, NULL, NULL, NULL, NULL, (size_t) 0, NULL,
                                (ub2)OCI_UTF16ID, (ub2)OCI_UTF16ID);

    printf("Status: %d\n", status);
    const char sqlstr [300] = "INSERT INTO ABCD_TABLE VALUES('966','31-AUG-15','19-JAN-17','901','31-DEC-12','1',\'\',\'\',\'\',\'\',\'\',\'\',\'ÜÜcreatectare,ää\')";
    OCIStmt *stmthp;

    printf("Statement: %s\n", sqlstr);

    status = OCIHandleAlloc((dvoid *)envhp, 
                 (dvoid **) &stmthp,
                 (ub4) OCI_HTYPE_STMT,  
                 (size_t) 0, 
                 (dvoid **) 0);


    printf("OCIHandleAlloc: %d\n", status);

    status = OCIStmtPrepare (stmthp, errhp, (const text *) sqlstr, strlen(sqlstr), OCI_NTV_SYNTAX, OCI_DEFAULT);

    if ( status != OCI_SUCCESS )
    {
        text errbuf[512];
        sb4 errcode = 0;
        switch (status)
        { 
            case OCI_SUCCESS:
                break;
            case OCI_SUCCESS_WITH_INFO:
                printf("ErrorOCI_SUCCESS_WITH_INFO\n");
                break;
            case OCI_NEED_DATA:
                printf("ErrorOCI_NEED_DATA\n");
                break;
            case OCI_NO_DATA:
                printf("ErrorOCI_NO_DATA\n");
                break;
            case OCI_ERROR:
                OCIErrorGet ((dvoid *) errhp, (ub4) 1, (text *) NULL, &errcode, errbuf, (ub4) sizeof(errbuf), (ub4) OCI_HTYPE_ERROR);
                wprintf(L"Error : %S, Error Code: %d\n", errbuf, errcode);
                break;
            case OCI_INVALID_HANDLE:
                printf("Error OCI_INVALID_HANDLE\n");
                break;
            default:
                break;
        }
    }

    printf("OCIStmtPrepare: %d\n", status);
    status = OCIStmtExecute(svchp, stmthp, errhp, (ub4)1, (ub4)1, NULL, NULL, OCI_COMMIT_ON_SUCCESS) ;
    printf("OCIExecute: %d\n", status);

    return status;
}

1 个答案:

答案 0 :(得分:1)

您正在初始化语句处理程序指针,但您似乎没有初始化错误处理程序指针:

status = OCIHandleAlloc((dvoid *) envhp,
             (dvoid **) &errhp,
             (ub4) OCI_HTYPE_ERROR,
             (size_t) 0,
             (dvoid **) 0);

或服务上下文指针:

status = OCIHandleAlloc((dvoid *) svchp,
             (dvoid **) &errhp,
             (ub4) OCI_HTYPE_SVCCTX,
             (size_t) 0,
             (dvoid **) 0);

不直接相关,但在inser语句中列出目标列通常是个好主意:

INSERT INTO ABCD_TABLE(col1, col2, ...) VALUES(...)

如果您使用null而不是转义空字符串,那么您的插入语句也会更容易阅读(尽管\'\'模式看起来很奇怪 - 不要认为你需要逃避那些? - 也许这不是意图);并且您依靠会话NLS设置隐式转换日期值,这也不是一个好主意。你应该真正绑定变量值,但这可能是你的下一步。