在我的应用程序中,新的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
请帮我解决这个问题。
答案 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转换为字符串,您可以使用您想要使用的任何库来操作该字符串。您必须指定您将接受的字符串的最大长度 - 或者进入动态绑定/获取的更复杂方面!