2015-03-25 2 views
0

В моем приложении в таблицу базы данных был добавлен новый столбец XMLType. Я должен читать и писать в эту таблицу с использованием Oracle C API. Как я получил из Интернета, базовым типом данных XMLType является CLOB, и, как я понимаю, тот же API, который я использовал для управления столбцами CLOB, должен также поддерживать столбцы XMLType.Как использовать столбцы OCI для XMLType в Oracle?

Моя таблица выглядит следующим образом (эта таблица не была фактической и использовалась как 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 следующим образом, а не она работает без каких-либо ошибок, даже для больших XMLs (более 4k)

SELECT A.MESSAGE.GETCLOBVAL() FROM STUDENT A 

Так одна часть была завершена.

Однако моя вторая часть, которая предназначена для вставки данных, не была выполнена.

My SQL является

INSERT INTO STUDENT (MESSAGE) VALUES (:1) 

Я связывание следующих данных.

В процессе выполнения он дает ошибку при заходе на посадку.

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

Пожалуйста, помогите мне в решении этой проблемы.

ответ

1

Это действительно непростая задача. Тем не менее, все еще сомнительно, каковы намерения Oracle со всей поддержкой XML. API был изменен между ver. 9i и 10i, и теперь снова были некоторые изменения в 12c. Но с другой стороны, для того, чтобы манипулировать XMLTYPE, поскольку это был «настоящий» XML, вам также нужна библиотека с именем libxml.a (кроме обычного libclntsh.so - oci.dll). Эта библиотека больше не загружается как часть «инструментария XDK», в InstantClient отсутствует нигде, и в OracleXE этого нет. Вам действительно нужно установить «толстый» клиент 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 библиотеки.

Лучше всего вам следует рассмотреть некоторые сложные примеры OCI на Metalink или прочитать исходный код некоторой библиотеки обложек OCI с открытым исходным кодом. Например, mine.. Но я должен признать, что сегодня есть лучшие и активно поддерживаемые сегодня .

0

Другим решением, которое гораздо проще в использовании, является указание типа SQLT_CHR. Затем сервер автоматически преобразует XMLType в строку, и вы можете манипулировать этой строкой, используя любую библиотеку, которую вы хотите использовать. Вам нужно указать максимальную длину строки, которую вы примете, или перейти к более сложным аспектам динамической привязки/выборки!

Смежные вопросы