3

我正在寻找一种简单的方法来确定 Oracle 中的字段是否为 NCLOB。

当我对字段执行属性获取时,我总是返回 112 (SQLT_CLOB),无论该字段是 CLOB 还是 NCLOB。这是我正在谈论的代码片段。

相关查询:'从 NCLOBTest2 中选择数据。, DATA在这种情况下是一个NCLOB 。

            ...
for I := 1 to CMaxFields do 
begin
  if oci.ParamGet( StmtHandle, OCI_HTYPE_STMT, FErrHandle, @APDesc, I ) <> OCI_SUCCESS then
    Break;
//At this Point APDesc refers to the field **DATA**.

while CheckError( oci.AttrGet( APDesc, OCI_DTYPE_PARAM, @APName, @ANameSz, OCI_ATTR_NAME, FErrHandle ) ) = OCI_STILL_EXECUTING do;

//APName and ANameSz, come back as 'DATA' and 8, respectively.  8 not 4, because it's a Unicode Environment.

while CheckError( oci.AttrGet( APDesc, OCI_DTYPE_PARAM, @ADbtype, nil, OCI_ATTR_DATA_TYPE, FErrHandle ) ) = OCI_STILL_EXECUTING do;
  DbType := ADbType;  //HERE IS THE PROBLEM, ADBTYPE IS ALWAYS SQLT_CLOB.

没有SQLT_NCLOB这样的东西吗?我需要知道该字段是 CLOB 还是 NCLOB,以便以后可以正确读取 N/CLOB。我知道如果我有一个实际的 LOBLocator 实例,我可以调用 LobCharSetForm 和 LobCharSetID,但这需要许多额外的步骤。

谢谢!

编辑:这是我在定义字段时尝试获取 LobCharSetID 所采取的步骤的摘要。类似的代码在绑定参数时才发现。也许有人可以告诉我我错过了哪些步骤。

Summary of coding steps:
        CheckError( oci.HandleAlloc( EnvHandle, @FStmtHandle, OCI_HTYPE_STMT, 0, nil ) );      //sse, allocating a statement handle
        CheckError( oci.StmtPrepare( StmtHandle, FErrHandle, PChar( ServerSQL ), Length( ServerSQL )*sizeof(char), OCI_NTV_SYNTAX, OCI_DEFAULT ) );
        while CheckError( oci.AttrGet( StmtHandle, OCI_HTYPE_STMT, @FStmtType, nil, OCI_ATTR_STMT_TYPE, FErrHandle ) ) = OCI_STILL_EXECUTING do;
        //EnvHandle and StmtHandle must be allocated properly to get this far.  FStmtType comes back correctly as OCI_STMT_SELECT (1).  
        I := 32768;
        oci.AttrSet( StmtHandle, OCI_HTYPE_STMT, @I, 0, OCI_ATTR_PREFETCH_MEMORY, FErrHandle );
        ACode := oci.StmtExecute( FSvcHandle, StmtHandle, FErrHandle, Nrows, Noffs, nil, nil, OCI_DEFAULT );
        oci.ParamGet( StmtHandle, OCI_HTYPE_STMT, FErrHandle, @APDesc, I ) <> OCI_SUCCESS
        //APDesc contains an OCIParam
        CheckError (oci.DescriptorAlloc (TOracle8Connection(aSQLParam.owner.owner.Connection).EnvHandle , @LobLocator, OCI_DTYPE_LOB, 0, nil));
        ACode := oci.DefineByPos( StmtHandle, @OCIDefine( FBind ), FErrHandle, Pos, @ALobLocator, MaxInt, SQLT_CHR, nil, nil, nil, OCI_DYNAMIC_FETCH );  
        CheckError(oci.LobLocatorIsInit(Connection.EnvHandle, FErrHandle, ALOBLocator, @isLobInitialized));  //RETURNS FALSE... UH OH!
        CheckError(oci.LobCharSetId(Connection.EnvHandle, FErrHandle, ALOBLocator, @lobCHAR_CODE));   //CRASH... OCI_INVALID_HANDLE  

最后两行是有问题的。我该怎么做才能正确轮询 LobLocator 的字符集。请注意 LobLocator 的字符集与定义句柄的字符集不同。定义句柄的字符集可能是 OCI_UTF16ID,而 Clob 的字符集可能是 OCI_WE8MSWIN1252。SQLCS 值也是如此,它也不必匹配。

4

0 回答 0