Я не первый, у кого есть эти проблемы, и перечислю несколько справочных сообщений ниже, но я все еще ищу правильное решение.
Мне нужно вызвать хранимую процедуру (база данных Oracle 10g) из веб-службы C #. На веб-сервере установлен клиент Oracle 9i, и я использую Microsofts System.Data.OracleClient
.
Процедура принимает XML как CLOB. Когда XML был больше 4000 байт (что, вероятно, является нормальным вариантом использования), я обнаружил следующую ошибку:
ORA-01460 - запрошено нереализованное или необоснованное преобразование
Я нашел 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 КБ или около того, что все еще очень вероятно в моем приложении. На этот раз ошибка связана с компилятором PL / SQL, который говорит:
ORA-06550: строка 1, столбец 87: PLS-00172: слишком длинный строковый литерал
После некоторого исследования я пришел к выводу, что решить проблему с помощью моего второго подхода просто невозможно.
После вышеупомянутых сообщений у меня есть следующие два варианта.
- Перейти на ODP.NET (потому что это должно быть ошибкой в устаревшем клиенте БД Microsoft)
- Вставляете CLOB-объект в таблицу и считываете сохраненный процесс оттуда
(В первом сообщении говорилось, что некоторые клиенты содержат ошибки, но мой (9i) не попадает в указанный диапазон версий 10g / 11g.)
Можете ли вы подтвердить, что остались только два варианта? Или есть другой способ мне помочь?
Просто для пояснения: XML не в конечном итоге будет сохранен в какой-либо таблице, но он обрабатывается хранимой процедурой, которая вставляет некоторые записи в некоторую таблицу на основе содержимого XML.
Мои соображения по поводу двух вариантов:
- Переключиться на ODP.NET сложно, потому что мне нужно установить его на веб-сервере, на котором у меня пока нет доступа к системе, и потому, что мы также можем захотеть развернуть фрагмент кода на клиентах, поэтому каждому клиенту придется установите ODP.NET как часть развертывания.
- Обход таблицы несколько усложняет клиентский код, а также требует некоторых усилий по адаптации / расширению подпрограмм PL / SQL в базе данных.
MyXML := '{0}';
string.Format()
заменяет'{0}'
на xml, однако'...'
является строковым литералом типа данныхVARCHAR2
(а неCLOB
). PL / SQL имеет ограничение 32 КБ наVARCHAR2
s, поэтому это не удается. - person MT0   schedule 12.07.2016