При работе с внешними источниками данных в 1С 8.2, в частности с базами данных Oracle, программисты часто сталкиваются с различными синтаксическими ошибками, которые возникают при выполнении запросов. Одной из таких распространенных ошибок является "ORA-00907: missing right parenthesis". В этой статье мы подробно разберем причину возникновения этой ошибки и предложим эффективные способы ее устранения, опираясь на опыт, описанный в форуме 1С и дополнительные технические данные.
Наш коллега столкнулся с ситуацией, когда при попытке выполнить запрос к базе данных Oracle через объект ВнешниеИсточникиДанных в 1С 8.2.19.130, система выдает ошибку "ORA-00907: missing right parenthesis". Это произошло при выполнении запроса, который включал оператор ЛЕВОЕ СОЕДИНЕНИЕ (LEFT JOIN) между двумя таблицами.
Рассмотрим код, который привел к ошибке:
Если ВнешниеИсточникиДанных.СПР.ПолучитьСостояние()=СостояниеВнешнегоИсточникаДанных.Отключен Тогда
ПараметрыПодключения=ВнешниеИсточникиДанных.СПР.ПолучитьОбщиеПараметрыСоединения();
ПараметрыПодключения.СтрокаСоединения="DRIVER={Microsoft ODBC for Oracle}; UID=Пользователь; PWD=Пароль; SERVER=Сервер;";
ПараметрыПодключения.СУБД="Oracle";
ВнешниеИсточникиДанных.СПР.УстановитьОбщиеПараметрыСоединения(ПараметрыПодключения);
КонецЕсли;
ВнешниеИсточникиДанных.СПР.УстановитьСоединение();
Query = Новый Запрос;
Query.Текст = "ВЫБРАТЬ
| FIDCMN.DOC_NUMBER,
| FIDCMN.DOC_DATE,
| FIBDOC.IS_UNLOAD
|ИЗ
| ВнешнийИсточникДанных.СПР.Таблица.APR_FIDCMN КАК FIDCMN
| ЛЕВОЕ СОЕДИНЕНИЕ ВнешнийИсточникДанных.СПР.Таблица.APR_FIBDOC КАК FIBDOC
| ПО FIBDOC.DOC_CODE = FIDCMN.DOC_CODE
|ГДЕ
| FIDCMN.RECORDID_DCTP = 722
| И НЕ FIDCMN.DOC_NUMBER ЕСТЬ NULL
| И FIDCMN.DOC_DATE МЕЖДУ &Нач И &Кон";
Query.УстановитьПараметр("Нач",НачалоПериода.Дата);
Query.УстановитьПараметр("Кон",КонецДня(КонецПериода.Дата));
Выборка=Query.Выполнить().Выбрать();
В данном случае для подключения используется драйвер Microsoft ODBC for Oracle. Ошибка, как мы видим, возникает на этапе выполнения запроса к внешней базе данных:
Ошибка выполнения запроса по причине: Ошибка внешней базы данных: ошибка при выполнении запроса по причине: Ошибка ODBC. SQLSTATE: 42000 Номер ошибки: 907 Описание: [Microsoft][ODBC driver for Oracle][Oracle]ORA-00907: missing right parenthesis
Самое интересное, что при выполнении аналогичного запроса через ADO (ActiveX Data Objects) к той же базе данных, все работает без каких-либо проблем. Это указывает на то, что проблема не в самой базе данных или в корректности SQL-запроса как такового, а скорее в способе его трансляции и выполнения через механизм Внешних Источников Данных 1С и используемый ODBC-драйвер.
Когда мы сталкиваемся с такой ошибкой, важно методично подойти к ее диагностике. Давайте разберем шаги, которые помогут нам локализовать проблемный участок запроса:
ORA-00907 часто указывает на синтаксическую проблему. Если запрос с одной таблицей работает, значит, проблема, скорее всего, кроется в добавлении новых элементов запроса: соединений (ЛЕВОЕ СОЕДИНЕНИЕ), условий (ГДЕ) или использовании агрегатных функций. Начнем с минимально рабочего запроса и постепенно будем добавлять элементы, каждый раз проверяя его выполнение.ГДЕ (WHERE) в дополнительные скобки, как это предложил один из участников форума. Несмотря на то, что для автора это не помогло, это стандартный диагностический шаг, который стоит выполнять.Вот рабочий ADO-запрос, который успешно выполняет нужную выборку:
Query = "Select fidcmn.doc_number,
fidcmn.doc_date,
fibdoc.doc_number,
fibdoc.is_unload
from apr.fidcmn
left outer join apr.fibdoc
on fibdoc.doc_code = fidcmn.doc_code
where fidcmn.recordid_dctp = 722 and fidcmn.doc_number is not null
and fidcmn.doc_date >= to_date('@@@@','DD-MM-YYYY')
and fidcmn.doc_date <= to_date('####','DD-MM-YYYY')";
Сравнивая этот запрос с запросом из 1С, мы можем выделить несколько ключевых отличий, которые могут быть источником проблемы:
ВнешнийИсточникДанных.СПР.Таблица.APR_FIDCMN КАК FIDCMN. В "чистом" Oracle SQL (как в ADO-запросе) ключевое слово AS для алиасов таблиц в секции FROM/JOIN часто опускается (например, from apr.fidcmn fidcmn или from apr.fidcmn без алиаса, если он не нужен для разрешения неоднозначности). Возможно, именно трансляция КАК для алиаса таблицы через Microsoft ODBC for Oracle приводит к синтаксической ошибке.apr.fidcmn, тогда как в 1С мы ссылаемся на ВнешнийИсточникДанных.СПР.Таблица.APR_FIDCMN. Хотя 1С должна корректно транслировать это, иногда явное указание схемы в ODBC может быть предпочтительнее. Однако, для Внешних Источников Данных 1С самостоятельно формирует ссылки на таблицы на основе их метаданных, определенных в конфигурации.to_date(). В запросе 1С мы устанавливаем параметры &Нач и &Кон, и 1С самостоятельно преобразует их в формат, понятный СУБД через ODBC. Хотя ошибка "missing right parenthesis" обычно не связана напрямую с датами, некорректная обработка типов данных или параметров драйвером может вызывать неожиданные синтаксические ошибки или быть вторичной проблемой.Основной причиной ошибки ORA-00907 при выполнении ЛЕВОЕ СОЕДИНЕНИЕ через Внешние Источники Данных в 1С 8.2 к Oracle, скорее всего, является несовместимость в интерпретации SQL-синтаксиса между тем, как 1С формирует запрос, и тем, как его обрабатывает промежуточный драйвер Microsoft ODBC for Oracle для СУБД Oracle.
В Oracle SQL синтаксис для LEFT JOIN может быть очень чувствителен к мелочам. Например, использование ключевого слова AS для алиасов таблиц в секции FROM/JOIN, хотя и допустимо в некоторых SQL-диалектах (например, T-SQL), в Oracle часто опускается или может быть интерпретировано по-другому, особенно старыми версиями драйверов или СУБД. Рабочий ADO-запрос демонстрирует, что без AS синтаксис корректен. Платформа 1С преобразует свой внутренний язык запросов в управляющие последовательности ODBC (ODBC Escape Sequences) и затем в нативный SQL СУБД. В этом процессе возможны ошибки трансляции, особенно для сложных конструкций, таких как LEFT JOIN, если драйвер не полностью поддерживает все нюансы или имеет свои особенности.
Наиболее эффективным и часто рекомендуемым решением в подобных ситуациях является использование нативных драйверов Oracle вместо стандартного Microsoft ODBC for Oracle. Драйверы от Microsoft иногда имеют ограничения или особенности в реализации, которые могут приводить к проблемам совместимости или некорректной трансляции сложных SQL-конструкций.
Мы предлагаем вам выполнить следующие шаги:
OraOLEDB.Oracle.1.Пример строки соединения для Oracle ODBC Driver:
// Пример для Oracle ODBC Driver (потребуется DSN или явное указание)
// С использованием DSN (Data Source Name):
ПараметрыПодключения.СтрокаСоединения="DSN=MyOracleDSN; UID=Пользователь; PWD=Пароль;";
// Без DSN, напрямую (может варьироваться в зависимости от версии драйвера)
// DRIVER={Oracle in OraClient12Home1}; DBQ=MyServiceAlias; UID=Пользователь; PWD=Пароль;
// Или, если это более общий синтаксис для ODBC драйвера Oracle:
// DRIVER={Oracle ODBC Driver}; Server=Сервер:Порт/ИмяСервиса; UID=Пользователь; PWD=Пароль;
Пример строки соединения для OraOLEDB.Oracle.1 (OLE DB провайдер):
// Если 1С поддерживает OLE DB провайдеров через Внешние Источники Данных
// (в 8.2 чаще использовались ODBC, но возможность подключения к OLE DB провайдерам есть)
// Provider=OraOLEDB.Oracle;Data Source=(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(HOST=Сервер)(PORT=1521)))(CONNECT_DATA=(SERVICE_NAME=ИмяСервиса)));User ID=Пользователь;Password=Пароль;
Как получить правильную строку соединения:
Мы можем легко сформировать правильную строку соединения, используя файл Universal Data Link (UDL). Это полезный инструмент для тестирования и получения строк подключения к различным базам данных:
test.udl.test.udl, чтобы открыть его свойства. Откроется окно "Свойства связи с данными".test.udl обычным текстовым редактором (например, "Блокнотом"). Внутри вы увидите сформированную строку соединения, которую можно скопировать и использовать в 1С.Переключение на нативный драйвер Oracle значительно увеличивает шансы на корректную трансляцию SQL-запросов и устранение синтаксических ошибок, таких как ORA-00907, поскольку нативные драйверы лучше "понимают" тонкости SQL-диалекта своей СУБД.
Если смена драйвера не решила проблему, или по каким-то причинам вы не можете его изменить, вам потребуется внимательно пересмотреть запрос 1С и попытаться максимально упростить его или адаптировать под особенности трансляции. Мы проанализируем возможные адаптации:
AS для алиасов таблиц в секции FROM/JOIN не является обязательным и иногда может вызывать проблемы с некоторыми драйверами или старыми версиями СУБД. В языке запросов 1С мы пишем ... КАК FIDCMN. Если бы была возможность, мы могли бы попробовать убрать КАК. Однако, язык запросов 1С довольно строго регламентирован, и прямое изменение синтаксиса в секции ИЗ может быть невозможно. В таких случаях проблема остается на стороне драйвера.ORA-00907 не напрямую связана с датами, некорректная обработка дат может усугубить ситуацию. Убедитесь, что формат дат в параметрах &Нач и &Кон не вызывает проблем при их передаче в Oracle. Нативные драйверы, как правило, лучше справляются с автоматическим преобразованием типов. Если проблема сохраняется, возможно, придется передавать даты в виде строк и использовать функции TO_DATE() в самом тексте запроса (это может потребовать динамического формирования текста запроса в 1С, что усложнит решение, так как 1С по умолчанию не позволяет использовать функции SQL-базы данных в своих запросах к внешним источникам).ЛЕВОЕ СОЕДИНЕНИЕ без условий, затем постепенно добавляйте условия в секции ГДЕ. Это поможет точно определить, какой именно элемент запроса вызывает ошибку. В нашем случае, как мы выяснили из обсуждения, проблема проявляется именно при добавлении соединения, что сильно указывает на проблему трансляции ЛЕВОЕ СОЕДИНЕНИЕ и/или алиасов таблиц.Исходя из опыта, наиболее вероятная причина кроется в специфике работы Microsoft ODBC for Oracle с конструкциями LEFT JOIN и алиасами таблиц, которые 1С формирует как ... КАК FIDCMN. Если драйвер некорректно транслирует это в нативный Oracle SQL, это может приводить к ошибке синтаксиса.
Для успешной и стабильной работы с Oracle через Внешние Источники Данных в 1С мы рекомендуем следующие подходы:
ПараметрыПодключения.СУБД="Oracle", чтобы 1С могла применить специфические оптимизации и правила трансляции для данной СУБД.TO_DATE, если драйвер работает корректно. 1С сама позаботится о правильном форматировании даты для СУБД.Ошибка "ORA-00907: missing right parenthesis" при работе с Внешними Источниками Данных Oracle в 1С 8.2 при использовании ЛЕВОЕ СОЕДИНЕНИЕ чаще всего связана с особенностями трансляции SQL-запроса через Microsoft ODBC for Oracle. Наиболее надежным решением является переход на нативные Oracle драйверы, такие как Oracle ODBC Driver или OraOLEDB.Oracle.1, которые обеспечивают лучшую совместимость и корректную интерпретацию синтаксиса. В случае, если смена драйвера невозможна, детальный анализ и упрощение запроса, а также сравнение с рабочим нативным SQL-запросом, помогут выявить и устранить проблему. Всегда начинайте диагностику с изоляции проблемы и постепенно усложняйте запрос, чтобы точно определить источник ошибки.