Как устранить ошибку ORA-00923 при работе с Oracle в 1С и корректно прочитать поля типа CLOB

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

Работа с внешними источниками данных в 1С — это мощный инструмент, который позволяет интегрировать сторонние базы данных непосредственно в программную среду предприятия. Однако при использовании СУБД Oracle разработчики часто сталкиваются со специфическими ошибками синтаксиса и проблемами типизации данных. Одной из самых коварных является ошибка "ORA-00923: ключевое слово FROM не найдено там, где оно ожидалось", а также трудности при получении больших текстовых объектов CLOB.

В этой статье мы подробно рассмотрим, почему возникают эти проблемы, как настроить систему для их предотвращения и какой программный код использовать для стабильного получения данных через COM-объекты ADODB.

Причины возникновения ошибки ORA-00923 в механизме «Внешние источники данных»

Когда мы добавляем таблицы Oracle через стандартный механизм 1С, платформа самостоятельно формирует SQL-запросы к СУБД. Ошибка ORA-00923 обычно сигнализирует о синтаксической ошибке. Разберем основные причины, которые к этому приводят:

  1. Чувствительность к регистру и двойные кавычки. Платформа 1С при формировании запроса часто заключает имена таблиц и полей в двойные кавычки (например, SELECT "Name" FROM "Table"). В Oracle идентификаторы, заключенные в кавычки, становятся чувствительными к регистру. Если в базе Oracle таблица создана как MY_TABLE (верхний регистр по умолчанию), а 1С запрашивает "my_table", Oracle не найдет объект и выдаст ошибку.
  2. Использование зарезервированных слов. Если имя колонки в Oracle совпадает с зарезервированным словом (например, DATE, COMMENT, ORDER, UID), драйвер может некорректно обработать запрос.
  3. Настройки драйвера ODBC. В настройках Oracle ODBC Driver существует параметр Metadata Id Default. Если он настроен некорректно, драйвер может неправильно интерпретировать метаданные, передаваемые платформой 1С.

Для решения проблемы в рамках штатного механизма рекомендуется проверить свойство «Имя в источнике» у каждой таблицы и поля в конфигураторе 1С. Оно должно в точности (включая регистр) соответствовать тому, как объект называется в схеме Oracle.

Переход на прямое подключение через ADODB

Если штатный механизм «Внешних источников данных» продолжает работать нестабильно, целесообразно рассмотреть вариант прямого подключения через COMОбъект. Это дает разработчику полный контроль над текстом SQL-запроса и процессом получения данных.

Рассмотрим пример кода для подключения и выполнения функции (или пакета) в Oracle, который возвращает набор записей:


ТаблицаЗаписей = Новый ТаблицаЗначений;
ТаблицаЗаписей.Колонки.Добавить("ID");
ТаблицаЗаписей.Колонки.Добавить("DOC_ID");
ТаблицаЗаписей.Колонки.Добавить("XML_DATA"); // Поле типа CLOB в Oracle

// Установка соединения (функция ПолучитьПодключение должна возвращать COM-объект ADODB.Connection)
Connect = ПолучитьПодключение();

Если Connect = Неопределено Тогда
    Сообщить("Не смогли подключиться к базе Oracle");
    Возврат;
КонецЕсли;

Command = Новый COMObject("ADODB.Command"); 
Command.ActiveConnection = Connect; 
// Указываем имя вызываемой функции или SQL-запрос
Command.CommandText = "CORPORATE.PKG_WS.GETDOCUMENTSFORSEND";
Command.CommandType = 8; // adCmdUnknown или adCmdStoredProc

RecordSet = Новый COMОбъект("ADODB.RecordSet");

Попытка
    RecordSet = Command.Execute(); 
Исключение
    Сообщить("Ошибка выполнения запроса: " + ОписаниеОшибки());
    Возврат;
КонецПопытки;

Пока RecordSet.EOF() = 0 Цикл 
    НоваяСтрока = ТаблицаЗаписей.Добавить();
    
    Для i = 0 По RecordSet.Fields.Count-1 Цикл
        ИмяКолонки = RecordSet.Fields.Item(i).Name;
        // Здесь может возникнуть проблема с типом CLOB
        НоваяСтрока[ИмяКолонки] = RecordSet.Fields.Item(ИмяКолонки).Value;    
    КонецЦикла;
    
    RecordSet.MoveNext();
КонецЦикла;

Проанализируем ситуацию: при выполнении этого кода данные обычных типов (числа, строки) переносятся корректно, но поле XML_DATA, имеющее в Oracle тип CLOB (Character Large Object), в 1С отображается как Неопределено. Это происходит потому, что LOB-объекты представляют собой указатели на данные, а не сами данные в явном виде.

Решение проблемы с типом данных CLOB

Выясним причину: тип CLOB может содержать гигабайты текста, поэтому драйвер не передает его «в лоб». Для получения этих данных в 1С есть несколько путей.

Способ 1. Преобразование на стороне Oracle.

Если вы знаете, что размер текста в поле не превышает лимитов строкового типа Oracle (традиционно 4000 символов, в новых версиях до 32767), самый простой способ — использовать функцию TO_CHAR в самом SQL-запросе или внутри хранимой процедуры:

SELECT TO_CHAR(XML_DATA) FROM MY_TABLE

В этом случае 1С получит обычную строку, и значение Неопределено исчезнет.

Способ 2. Использование метода GetChunk.

Если данные действительно большие (например, тяжелые XML-файлы), необходимо считывать их по частям (порциями). Разберем, как изменить цикл обхода RecordSet для работы с большими объектами:


// Фрагмент кода для чтения CLOB
РазмерПоля = RecordSet.Fields.Item("XML_DATA").ActualSize;
Если РазмерПоля > 0 Тогда
    // Считываем данные порциями по 1024 символа
    СодержимоеCLOB = "";
    Порция = 1024;
    Прочитано = 0;
    Пока Прочитано < РазмерПоля Цикл
        ЧастьДанных = RecordSet.Fields.Item("XML_DATA").GetChunk(Порция);
        СодержимоеCLOB = СодержимоеCLOB + ЧастьДанных;
        Прочитано = Прочитано + Порция;
    КонецЦикла;
    НоваяСтрока.XML_DATA = СодержимоеCLOB;
Иначе
    НоваяСтрока.XML_DATA = "";
КонецЕсли;

Способ 3. Смена провайдера на OraOLEDB.

Проанализируем строку подключения. Часто для связи используется провайдер MSDASQL (Microsoft OLE DB Provider for ODBC). Однако при работе с Oracle гораздо эффективнее использовать родной провайдер OraOLEDB.Oracle.

При использовании этого провайдера в строке подключения можно указать параметр SPPrmsLOB=T. Это заставляет провайдер автоматически обрабатывать LOB-параметры и передавать их в понятном для COM-клиента (которым является 1С) строковом виде, что зачастую избавляет от необходимости использовать GetChunk.

Рекомендации по настройке окружения

Чтобы минимизировать ошибки взаимодействия 1С и Oracle, придерживайтесь следующих правил:

Использование прямого обращения через ADODB с правильной обработкой CLOB через GetChunk или TO_CHAR является наиболее надежным способом интеграции 1С и Oracle, позволяющим обойти ограничения стандартных механизмов платформы и специфические ошибки синтаксиса СУБД.

← На главную