При работе с внешними источниками данных в 1С (особенно с СУБД Oracle через ODBC-драйвер) разработчики часто сталкиваются с ошибкой SQLSTATE: 22018, Номер ошибки: 1722, Описание: [Oracle][ODBC][Ora]ORA-01722: неверное число. Эта проблема может носить «плавающий» характер: данные то записываются успешно, то вызывают исключение при идентичных на первый взгляд условиях. В этой статье мы подробно разберем причины возникновения этой ошибки и методы ее устранения.
Ошибка ORA-01722 возникает в тот момент, когда Oracle пытается преобразовать строку в число, но строка содержит символы, которые не могут быть интерпретированы как часть числового значения. В контексте 1С и внешних источников данных это происходит при выполнении команд INSERT или UPDATE, когда платформа передает данные в поля с типом NUMBER, FLOAT или INTEGER.
Рассмотрим основные факторы, провоцирующие эту ситуацию, и способы их локализации.
Проанализируем ситуацию с параметрами NLS (National Language Support). Oracle определяет формат представления чисел на основе параметра NLS_NUMERIC_CHARACTERS. Если этот параметр настроен на использование точки в качестве десятичного разделителя, а 1С передает число с запятой (или наоборот), СУБД выдаст ошибку 1722.
Почему ошибка может возникать периодически? Разберем по шагам:
NLS_LANG).Как исправить: Проверьте значение NLS_LANG в реестре на сервере 1С (путь: HKEY_LOCAL_MACHINE\SOFTWARE\ORACLE\KEY_OraClient...). Рекомендуется привести настройки операционной системы (Региональные стандарты) к единому виду, где разделителем дробной части является точка, либо убедиться, что настройки драйвера соответствуют ожиданиям базы данных.
Выясним причину, связанную с «невидимыми» символами. В 1С при преобразовании числа в строку для отображения часто используется функция Формат() или стандартное строковое представление, которое вставляет неразрывный пробел (символ с кодом 160) в качестве разделителя тысяч.
Если данные перед попаданием во внешний источник проходят через промежуточные преобразования, в числовое поле может попасть строка вида «1 000,50». Для Oracle пробел между «1» и «000» является недопустимым символом для типа NUMBER.
Пример кода для очистки данных:
// Перед записью во внешний источник данных убеждаемся, что число чистое
ЧислоДляЗаписи = СтрЗаменить(СтрокаСЧислом, Символы.НПП, ""); // Удаляем неразрывные пробелы
ЧислоДляЗаписи = СтрЗаменить(ЧислоДляЗаписи, " ", ""); // Удаляем обычные пробелы
Проанализируем, как 1С обрабатывает пустые значения. Иногда при попытке записи «пустого» числового значения платформа может передать пустую строку '' вместо значения NULL. В Oracle попытка неявного приведения TO_NUMBER('') всегда приводит к ошибке ORA-01722.
Рассмотрим рекомендации по работе с полями:
NULL.NULL недопустим.Посмотрим на техническую сторону взаимодействия. Драйвер Oracle in OraClient11g_home1 имеет ряд известных проблем с передачей параметров в 64-битных системах. В некоторых случаях он некорректно интерпретирует метаданные полей, передаваемые платформой 1С.
Решение: Специалисты рекомендуют обновить клиентскую часть Oracle до версии 12c или выше (даже если сама база данных остается версии 11g). В настройках ODBC DSN на вкладке «Workarounds» попробуйте включить или выключить опцию «Numeric Settings», которая заставляет драйвер использовать настройки клиентского окружения.
Если в таблице много числовых полей, выясним, на каком именно происходит сбой, используя следующие методы:
SQLExecute или SQLPutData. Там будут видны конкретные значения параметров, которые 1С передает в Oracle.Попросите администратора базы данных включить трассировку для вашей сессии (через DBMS_MONITOR.SESSION_TRACE_ENABLE). Это позволит увидеть финальный SQL-запрос, который «прилетает» в базу, и понять, в каком формате передаются числа.
Подводя итог, можно сказать, что ORA-01722 — это почти всегда проблема формата данных. Для стабильной работы внешних источников данных 1С с Oracle придерживайтесь следующих правил:
NLS_LANG клиента Oracle.ВнешнийИсточникДанныхНаборЗаписей следите за тем, чтобы типы данных 1С строго соответствовали типам данных Oracle (например, Число в 1С с соответствующей точностью).Соблюдение этих рекомендаций позволит избежать «магических» ошибок, которые исчезают при отладке, и обеспечит надежную интеграцию систем.