Проблемы с вызовом хранимой процедуры из C # с большим CLOB

Я не первый, кто сталкивается с этими проблемами, и перечислю несколько справочных сообщений ниже, но все еще ищу правильное решение.

Мне нужно вызвать хранимую процедуру (база данных Oracle 10g) из веб-службы C #. На веб-сервере установлен клиент Oracle 9i, и я использую Microsoft System.Data.OracleClient .

Процедура принимает XML как CLOB. Когда XML-код превышал 4000 байт (что, скорее всего, в обычном случае использования), я наткнулся на следующую ошибку:

ORA-01460 - запрошено невыполненное или необоснованное преобразование

Я обнаружил этот , этот и этот пост.

Далее я нашел многообещающий обходной путь, который не вызывает хранимую процедуру непосредственно из 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: line1, колонка 87: PLS-00172: строковый литерал слишком длинный

После некоторых исследований я пришел к выводу, что решить проблему вторым подходом просто невозможно,

После вышеупомянутых постов у меня есть следующие два options.

] ( В первом посте говорилось, что некоторые клиенты глючат, но мой (9i) не попадает в упомянутый диапазон версий 10g / 11g.)

Можете ли вы подтвердить, что это только два оставшихся варианта ? Или есть другой способ помочь мне?

Просто чтобы уточнить: XML не будет в конечном итоге сохранен ни в одной таблице, но он обрабатывается хранимой процедурой, которая вставляет некоторые записи в некоторую таблицу на основе содержимого XML.

Мои соображения по поводу двух вариантов:

  • Переключение на ODP.NET затруднено, поскольку мне нужно установить его в Интернете. сервер, к которому у меня пока нет доступа к системе, и потому что мы могли бы также захотеть развернуть часть кода на клиентах, поэтому каждый клиент должен был бы установить ODP.NET как часть развертывания.
  • В обход таблица делает клиентский код немного более сложным, а также требует определенных усилий для адаптации / расширения базы данных PL / SQL.

18
задан Community 23 May 2017 в 10:28
поделиться

2 ответа

Я обнаружил, что - это еще один способ решения проблемы! Мой коллега сэкономил мне время, указав на этот блог , в котором говорится:

Установите значение параметра, когда BeginTransaction уже был вызвал DbConnection.

А может быть проще? Блог относится к Oracle.DataAccess , но он также хорошо работает с System.Data.OracleClient .

На практике это означает:

varcmd = new OracleCommand("LoadXML", _oracleConnection);
cmd.CommandType = CommandType.StoredProcedure;

var xmlParam = new OracleParameter("XMLFile", OracleType.Clob);
cmd.Parameters.Add(xmlParam);

// DO NOT assign the parameter value yet in this place

cmd.Transaction = _oracleConnection.BeginTransaction();
try
{
    // Assign value here, AFTER starting the TX
    xmlParam.Value = xmlWithWayMoreThan4000Characters;

    cmd.ExecuteNonQuery();
    cmd.Transaction.Commit();
}
catch (OracleException)
{
    cmd.Transaction.Rollback();
}
13
ответ дан 30 November 2019 в 09:11
поделиться

Думаю, я просто погуглил это, чтобы вы получали дешевые баллы, но здесь есть отличное объяснение:

http://www.orafaq.com/forum/t/48485/0 /

Обычно вы не можете использовать более 4000 символов в строковом литерале, а если вам нужно сделать больше, вы должны использовать хранимую процедуру. Затем вы ограничены максимумом 32 КБ, поэтому вам нужно «разбить» вставки. Блеч.

-Oisin

0
ответ дан 30 November 2019 в 09:11
поделиться
Другие вопросы по тегам:

Похожие вопросы: