如何在Oracle中使用OCI for XMLType列?

时间:2015-03-25 06:56:03

标签: c oracle oci

在我的应用程序中,新的XMLType列已添加到数据库表中。我必须使用Oracle C API读取和写入该表。 当我从网上获取时,XMLType的基础数据类型是CLOB,根据我的理解,我用来管理CLOB列的相同API也应该支持XMLType列。

我的表格如下(此表格不是实际的表格并用作POC)。

CREATE TABLE STUDENT
(
    NIC NUMBER(10),
    MESSAGE XMLTYPE
);

选择数据的SQL

SELECT MESSAGE FROM STUDENT

但是在获取数据时,它给了我以下错误:

ORA-00932: inconsistent datatypes: expected CLOB got OPAQUE TYPE

我将变量定义如下。

pLocator = new OCILobLocator*;
*pLocator = NULL;

OCIDescriptorAlloc(p_DBCon->p_env, (dvoid **)pLocator, OCI_DTYPE_LOB, 
    (size_t)0, (dvoid **)0);

b_IsErr = OCIDefineByPos(p_sql, &p_dfn, p_DBCon->p_err, iPos, 
    (dvoid*)pLocator, -1, SQLT_CLOB, 0, 0, 0, OCI_DEFAULT);

但是,我按如下方式修改了SQL,即使对于较大的XML(超过4k),它也没有任何错误。

SELECT A.MESSAGE.GETCLOBVAL() FROM STUDENT A

所以有一部分已经完成。

但是,我用于插入数据的第二部分失败了。

我的SQL是

INSERT INTO STUDENT (MESSAGE) VALUES (:1)

我按如下方式进行数据绑定。

b_IsErr = OCIBindByPos(p_sql, &p_bnd, p_DBCon->p_err, iPos,
    (dvoid*)pzValue, iSize, SQLT_STR, 0, 0, 0, 0, 0, OCI_DEFAULT);

在执行中它给出了错误。

ORA-01461: can bind a LONG value only for insert into a LONG column

请帮我解决这个问题。

2 个答案:

答案 0 :(得分:1)

这真的不是一件容易的事。特别是Oracle仍然怀疑Oracle对整个XML支持的意图是什么。 API之间的API发生了变化。 9i和10i现在再次在12c中有一些变化。但另一方面,为了操纵XMLTYPE,它是真实的" XML还需要一个名为libxml.a的库(除了通常的libclntsh.so - oci.dll)。这个库不能作为" XDK工具包"的一部分下载,在InstantClient中缺少nether,OracleXE中也没有。你真的需要安装" thick" Oracle客户端获取此库。

然后你必须将XML列绑定,就好像它是一个"复杂的"类型。它真的 是一个名为SYS.XMLTYPE的复杂类型(此SYS.前缀很重要)。

所以它应该是:

b_IsErr = OCIBindByPos(p_sql, &p_bnd, p_DBCon->p_err, iPos,
(dvoid*)pzValue, iSize, SQLT_NTY, 0, 0, 0, 0, 0, OCI_DEFAULT);

一旦绑定为SQLT_NTY,就必须使用函数来操作它 来自libxml.a库。

最好你应该查看Metalink上的一些复杂的OCI示例或者阅读一些开源OCI包装器库的源代码。例如mine.。 但我必须承认,今天有更好的和积极的维护 今天的库。

答案 1 :(得分:0)

另一种更容易使用的解决方案是将SQLT_CHR指定为类型。然后服务器会自动将XMLType转换为字符串,您可以使用您想要使用的任何库来操作该字符串。您必须指定您将接受的字符串的最大长度 - 或者进入动态绑定/获取的更复杂方面!