我正在寻找一种简单的方法来确定Oracle中的字段是否为NCLOB。
当我在字段上执行属性获取时,无论字段是CLOB还是NCLOB,我总是返回112(SQLT_CLOB)。这是我正在谈论的代码片段。
相关查询:'从NCLOBTest2中选择数据。,数据在这种情况下是 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的Charset。请注意,LobLocator的charset与define handle的charset不同。 define handle的charset可能是OCI_UTF16ID,而Clob的charset可能是OCI_WE8MSWIN1252。对于SQLCS值也是如此,它也不必匹配。