Я не первый, кто имеет эти проблемы, и перечисляю некоторые справочные сообщения ниже, но я все еще ищу подходящее решение.Вопросы, вызывающие хранимую процедуру с C# с большим CLOB
Мне нужно вызвать хранимую процедуру (базу данных Oracle 10g) из веб-службы C#. На веб-сервере установлен клиент Oracle 9i, и я использую Microsoft System.Data.OracleClient
.
Процедура принимает XML как CLOB. Когда XML было более 4000 байт (что, вероятно, в нормальном случае использования), я наткнулся на следующее сообщение об ошибке:
ORA-01460 - unimplemented or unreasonable conversion requested
Я нашел this, this и this пост.
Далее я нашел многообещающее обходное решение, которое не вызывает хранимую процедуру непосредственно из C#, но вместо этого определяет часть анонимного кода PL/SQL. Этот код запускается как OracleCommand. XML встраиваются в виде строки буквальным и вызов процедуры осуществляются внутри этого фрагмента кода:
private const string LoadXml =
"DECLARE " +
" MyXML CLOB; " +
" iStatus INTEGER; " +
" sErrMessage VARCHAR2(2000); " +
"BEGIN " +
" MyXML := '{0}'; " +
" iStatus := LoadXML(MyXML, sErrMessage); " +
" DBMS_OUTPUT.ENABLE(buffer_size => NULL); " +
" DBMS_OUTPUT.PUT_LINE(iStatus || ',' || sErrMessage); " +
"END;";
OracleCommand oraCommand = new OracleCommand(
string.Format(LoadXml, xml), oraConnection);
oraCommand.ExecuteNonQuery();
К сожалению, этого подхода в настоящее время не удается, как только XML составляет более 32 килобайтов или так, который по-прежнему очень вероятен в моей заявке. На этот раз ошибка связана с/SQL компилятор PL, который говорит:
ORA-06550: line1, column 87: PLS-00172: string literal too long
После некоторых исследований я делаю вывод, что это просто не представляется возможным решить проблему с моим вторым подходом.
После вышеупомянутых сообщений у меня есть следующие два варианта.
- Switch to ODP.NET (потому что она должна быть ошибкой в устаревшем клиенте БД Microsoft Office)
- Insert the CLOB into a table и сделать ХП чтение оттуда
(The first post сказал, что некоторые клиенты глючат, но (9i) не попадает в указанный диапазон версий 10g/11g.)
Можете ли вы подтвердить, что это осталось только два варианта? Или есть другой способ помочь мне?
Просто для уточнения: в XML не в конечном итоге будет сохранен в любой таблице, но она обрабатывается хранимой процедурой, которая вставляет некоторые записи в некоторых таблицах на основе содержимого XML.
Мои соображения по поводу двух вариантов:
- Переключение ODP.NET сложно, потому что я должен установить на веб-сервере, на котором я не имею доступа к системе до сих пор, и потому, что мы могли бы также хотят развернуть кусок кода на клиентах, поэтому каждый клиент должен будет установить ODP.NET как часть развертывания.
- Обход по таблице делает код клиента довольно сложным, а также требует немалых усилий для базы данных, адаптирующей/расширяющей подпрограммы PL/SQL.
BLOB или CLOB, опечатка. – Benny
@Benny: Проблема существует для больших объектов LOB, следовательно, ссылки на BLOB-сообщения, но я боролся с CLOB. Я не могу найти опечатку в своем посте ... – chiccodoro
'MyXML: = '{0}';' 'string.Format()' заменяет ''{0}'' на xml - однако, '' ... ''является строковым литералом, который имеет тип данных VARCHAR2 (а не' CLOB'). [PL/SQL имеет ограничение 32k] (http://docs.oracle.com/cd/B28359_01/appdev.111/b28370/datatypes.htm#i43252) на 'VARCHAR2', поэтому это не работает. – MT0