Если после миграции вызов не находит процедуру, не запускайте перенос заново. Сначала сравните три состояния объекта: в Oracle, в SQL-файле Ora2Pg и в PostgreSQL.

Так вы отделите пропуск при экспорте от ошибки загрузки и нерабочей конвертации. До запуска связанного сценария 1С нужна ведомость: где лежит каждая процедура, под каким именем она создана и сохранила ли прежнее поведение.

Найдите точку, где пропала процедура

Успешное завершение команды не подтверждает перенос каждой процедуры. По документации Ora2Pg инструмент подключается к Oracle, сканирует структуру и формирует SQL-файлы. Затем эти файлы загружают в PostgreSQL отдельным этапом.

Между исходной базой и готовым объектом есть три контрольные точки:

Что видноГде искатьКакой вывод можно сделать
Процедура есть в Oracle, но отсутствует в выгруженном SQLПараметры экспорта, выбранная схема, состав пакетаОбъект не вошёл в выгрузку
Определение есть в SQL, но объекта нет в PostgreSQLЖурнал загрузки и сообщения PostgreSQLЭкспорт сработал, загрузка объекта — нет
Объект создан, но вызов его не находитИмя, тип объекта, схема и сигнатураПроцедура могла стать функцией или получить другое имя
Объект вызывается, но результат отличаетсяТело функции, состояние сеанса, транзакции, курсорыСинтаксис перенесён, поведение — нет

Говорить «Ora2Pg удалил процедуру» рано, пока вы не сравнили все три состояния.

Начните с Oracle. Зафиксируйте схему, пакет, имя процедуры и список параметров. Не полагайтесь на имя из вызова приложения: оно может скрывать обращение к члену пакета.

Затем найдите определение в выгруженном SQL. Ищите не только исходное имя. По разбору Laniakea Consulting, при экспорте пакета Ora2Pg разворачивает его члены в отдельные функции PL/pgSQL и добавляет к имени префикс пакета.

Например, член BILLING.CALC_TOTAL может оказаться отдельной функцией с именем, собранным из названия пакета и процедуры. Точное написание сверяйте по своему SQL-файлу: предоставленные материалы не задают единый шаблон регистра и разделителей.

Если определение найдено, проверьте соответствующий объект в PostgreSQL. Отсутствие объекта при наличии DDL переводит проверку на этап загрузки. Повторный экспорт здесь не поможет.

Проверьте охват экспорта

Если процедуры нет уже в SQL, сначала проверьте схему и тип выгрузки. Разбирать PL/SQL в этот момент рано: конвертер мог не получить нужный объект.

Документация Postgres Pro описывает для ora2pgpro три параметра, которые влияют на такой сценарий:

Эти имена относятся к ora2pgpro. Не переносите их на открытую версию Ora2Pg без сверки с документацией установленного выпуска.

Проверьте также фактическую команду запуска. По документации Postgres Pro параметры командной строки перекрывают значения из ora2pgpro.conf. Если одиночная директива повторяется в конфигурации, работает последнее значение.

Отсюда типовой сбой: в конфигурации указана нужная схема, а скрипт запуска передаёт другую через командную строку. Команда завершается штатно, но нужного пакета в выгрузке нет.

Соберите параметры одного запуска в короткую карточку:

ПараметрЧто зафиксироватьЧто считать ошибкой
Тип экспортаФактическое значение из команды и конфигурацииВ выгрузку не входят пакеты или процедуры
Схема OracleИмя схемы, из которой читаются объектыПакет лежит в другой схеме
Конвертация PL/SQLВключена ли она при этом запускеКод выгружен без требуемого преобразования
Приоритет настроекКакие значения пришли из командной строкиКоманда перекрыла проверенную конфигурацию

Если схема и пакет вошли в SQL, охват экспорта подтверждён. Дальше проверяйте результат конвертации и загрузки.

Пакет Oracle превращается в набор отдельных функций

Oracle хранит процедуры и функции внутри пакета. PostgreSQL такой способ организации напрямую не повторяет.

Dalibo в руководстве по переносу процедур пишет, что Ora2Pg преобразует пакеты Oracle в схемы PostgreSQL. Разбор Laniakea Consulting уточняет другую сторону преобразования: члены пакета становятся отдельными функциями с префиксом имени пакета.

Из-за этого прежний вызов может сломаться, хотя объект присутствует в базе. Приложение продолжает искать процедуру пакета, а в PostgreSQL уже лежит самостоятельная функция под другим именем.

Для каждой процедуры запишите:

Этот список нужен не для отчёта о миграции. По нему вы исправите вызовы и заметите коллизии имён до переключения 1С.

Отделите созданный объект от рабочего

Наличие функции в PostgreSQL подтверждает только выполнение DDL. Оно ничего не говорит о переменных пакета, курсорах и независимых транзакциях.

Laniakea Consulting выделяет четыре группы конструкций, которые Ora2Pg не переносит в рабочем виде автоматически. Это не статистика отказов, а четыре категории из опубликованного разбора.

Конструкция OracleЧто может остаться после конвертацииКуда двигать ручную доработку
Переменные уровня пакетаФункции с обращением к неопределённой переменнойПростое состояние хранить через set_config и current_setting, сложное — во временной таблице
SYS_REFCURSORКомментарий или заглушка вместо возвращаемого типаВыбрать RETURNS TABLE, RETURNS SETOF либо RETURNS refcursor
PRAGMA AUTONOMOUS_TRANSACTIONКод без прежней независимости транзакцийОтдельно спроектировать запись, которая переживает откат основной транзакции
DBMS_OUTPUT.PUT_LINEУдалённый вызов либо неразрешимая ссылкаДля диагностического вывода использовать RAISE NOTICE
DBMS_PIPEВызов без прямого аналогаПеренести обмен на LISTEN/NOTIFY либо во внешний сервис сообщений

Созданная функция ещё не доказывает перенос процедуры по смыслу.

Переменные пакета теряют состояние

В Oracle переменная уровня пакета живёт в сеансе. Несколько процедур одного пакета могут читать и менять её между вызовами.

После разворачивания пакета остаются отдельные функции PostgreSQL. По разбору Laniakea Consulting, Ora2Pg не создаёт автоматическую замену такому состоянию. Объявление может исчезнуть, а обращения к переменной — остаться в теле функции.

Простое скалярное значение можно хранить через set_config и current_setting. Для составного состояния лучше подходит временная таблица. Выбор зависит от того, кто читает значение, когда его сбрасывают и должно ли оно переживать транзакцию.

Проверяйте не только компиляцию. Выполните последовательность из нескольких вызовов в одном сеансе и сравните её с Oracle. Отдельный успешный вызов не обнаружит потерю состояния между процедурами.

SYS_REFCURSOR требует нового контракта

Oracle-процедуры часто возвращают набор строк через SYS_REFCURSOR. Laniakea Consulting пишет, что Ora2Pg оставляет для такого типа заглушку и не завершает преобразование автоматически.

В PostgreSQL результат можно вернуть через RETURNS TABLE, RETURNS SETOF или RETURNS refcursor. Эти варианты требуют разных вызовов со стороны приложения.

RETURNS TABLE убирает ручное управление курсором, но меняет контракт вызова. RETURNS refcursor ближе к приложению, которое уже работает с выходным курсором. Решение принимайте вместе с кодом, который забирает результат.

Автономную транзакцию нельзя заменить механически

PRAGMA AUTONOMOUS_TRANSACTION даёт Oracle-процедуре собственную транзакцию. Она может записать событие и зафиксировать его, даже если основная операция позже откатится.

По разбору Laniakea Consulting, прямого аналога этой конструкции в PostgreSQL нет. Поэтому удаление директивы меняет поведение, даже если остальной код выполняется.

Сначала установите назначение независимой транзакции. Для аудита потребуется механизм, который не откатится вместе с рабочей операцией. Для обычной записи отдельная фиксация могла быть лишней частью старой реализации.

Не выбирайте замену только ради совпадения синтаксиса. Здесь меняется граница транзакции, а вместе с ней — результат при ошибке.

Вызовы DBMS_* надо разбирать по назначению

Одинакового заменителя для пакетов DBMS_* нет. Смотрите, какую работу выполняет каждый вызов.

Для DBMS_OUTPUT.PUT_LINE PostgreSQL использует RAISE NOTICE. Это замена диагностического вывода, но не канал передачи данных приложению.

Для DBMS_PIPE прямого аналога нет. Laniakea Consulting предлагает LISTEN/NOTIFY или обмен сообщениями вне СУБД. Такой участок требует нового проекта взаимодействия, а не правки имени функции.

Сверьте тип объекта и сигнатуру

После переноса Oracle-процедура может стать функцией PostgreSQL. Старый вызов при этом перестаёт работать.

Руководство Dalibo фиксирует различие: процедуру PostgreSQL вызывают через CALL, функцию — через SELECT или PERFORM. Процедуру Oracle с параметрами OUT при переносе нужно преобразовать в функцию PostgreSQL.

Сверьте сигнатуру по полям, а не одной строкой:

ПолеЧто было в OracleЧто проверить в PostgreSQL
Тип объектаПроцедура или функцияНе изменился ли способ вызова
Режим параметраIN, OUT, IN OUT после имениIN, OUT, INOUT перед именем
Возвращаемое значениеRETURN в объявлении функцииRETURNS и соответствующий тип
Локальные переменныеОбъявления перед исполняемым блокомБлок DECLARE
ТелоСинтаксис PL/SQLКорректный PL/pgSQL
ЯзыкПодразумевается контекстом OracleУказан LANGUAGE plpgsql

Если объект найден, но старый вызов не работает, сначала проверьте эту таблицу. Переписывать тело функции до сверки контракта не нужно.

Отдельно смотрите порядок параметров. Dalibo указывает, что Oracle ставит режим IN или OUT после имени, а PostgreSQL — перед ним. Режим IN OUT превращается в INOUT.

Проверьте и значения по умолчанию. Оба продукта принимают DEFAULT, но сокращённая запись различается: Oracle использует :=, PostgreSQL — =. Такая деталь может остановить создание объекта ещё при загрузке SQL.

Проверьте поведение на отдельной базе PostgreSQL

Не допускайте связанный сценарий 1С к новой процедуре сразу после создания объекта. Сначала выполните контрольные вызовы на отдельной базе PostgreSQL.

Для каждого вызова возьмите одинаковые входные данные в Oracle и PostgreSQL. Сравните возвращаемое значение, изменённые строки, сообщения об ошибках и побочные записи.

Предоставленные материалы не описывают автоматическую проверку таких процедур средствами 1С. Поэтому не считайте запуск клиента доказательством эквивалентности. Он покажет лишь тот путь, до которого дошёл конкретный сценарий.

Особое внимание нужно четырём участкам:

Именно здесь синтаксически допустимая функция может дать другой результат.

Ведомость приёмки процедуры

Заведите одну строку на каждый переносимый член пакета. Отметки «экспорт завершён» для такой ведомости недостаточно.

ПроверкаЧто записатьУсловие приёмки
Объект в OracleСхема, пакет, имяИсходная процедура найдена
Объект в SQLФайл и новое имяОпределение присутствует в выгрузке
Объект в PostgreSQLСхема, имя, типDDL выполнен, объект создан
СигнатураПараметры и возвращаемый типНовый вызов соответствует контракту
Особые конструкцииСостояние, курсоры, транзакции, DBMS_*Для каждой конструкции выбрана замена
Контрольный вызовВходные данные и наблюдаемый результатРезультат совпал с Oracle
Сценарий 1СОперация, которая обращается к объектуСценарий прошёл после отдельной проверки

Процедура перенесена только тогда, когда объект найден, создан, вызывается новым способом и даёт ожидаемый результат.

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

Короткий порядок на текущую проверку:

  1. Найдите процедуру в Oracle.
  2. Найдите её или развёрнутый член пакета в SQL.
  3. Проверьте схему, тип экспорта и конвертацию PL/SQL.
  4. Найдите созданный объект в PostgreSQL.
  5. Сверьте имя, тип и сигнатуру.
  6. Отметьте конструкции, требующие ручной замены.
  7. Сравните контрольные вызовы.
  8. Только после этого запускайте связанный сценарий 1С.
ora2pg oracle postgresql миграция базы сервер 1с