При переносе при переносе базы с MS-SQL Server 2005 на Oraclе 11gR2 возникла задача перевода динамического SQL. Исходная система содержала более 3000 динамических запросов в примерно 850 хранимых процедурах. Весь динамический SQL так же должен быть переведён на язык целевой СУБД и преобразован согласовано с основным кодом. Например, должны быть переименованы таблицы.
Для работы с динамически формируемыми строками существуют абстрактный лексический и синтаксический анализы, однако они непосредственно не применимы для задач трансформации, так как не сохраняют привязку к исходному коду. Кроме того, синтаксический анализ не учитывает семантику, которая для трансляции очень важна. Однако, он тоже может быть полезен при миграции: можно уточнить трансляцию, выявив важные для миграции участки (создание временных таблиц, факт присваивания в переменную для уточнения достигающих определений, наличие возвращаемого рекордсета, и пр.).
Основная цель при трансформации — вычисление для всех переменных, участвующих в формировании запроса, новых значений, таких, чтобы в результирующей системе так же формировался корректный запрос.
В результате развития идеи абстрактного синтаксического анализа в автоматизированную трансформацию в данном проекте удалось автоматически обработать 50% запросов. Кроме того, удалось провести согласованное переименование временных таблиц и выявить запросы, пораждающие выборки. Последнее позволило автоматически преобразовать их в создание курсора и скорректировать сигнатуры процедур.
Важным аспектом является производительность решения, так как в переводимой системе существовало большое количество динамических запросов со сложной логикой формирования, задействующей десятки и более присваиваний и условных ветвлений. В общем случае алгоритм, непосредственно основанный на абстрактном синтаксическом анализе, требовал экспоненциальные ресурсы. Был предложен и реализован механизм фильтрации результатов синтаксического анализа, который существенно уменьшает количество деревьев для сложных запросов.
Основную сложность вызвало вычисление новых значений для переменных. Во-первых, причиной тому наличие элементов, которые непосредственно не представлены в дереве (запятые, скобки, знаки бинарных операций). Литералы, соответсвующе данным элементам могут являться отдельными переменными при формировании строки динамического запроса. Во-вторых, конструкции, требующие серьёзных структурных преобразовани. Например, при трансляции из T-SQL в PL-SQL это трансляция сложного UPDATE .. SELECT в MERGE. При сильных преобразованиях становится необходимо создавать новые перменные и вычислять их значения согласовано с соответствующими исходными переменными.
В целом можно сказать, что был разработан алгоритм трансформации, позволяющий сэкономить время на ручную миграцию динамического SQL. В докладе будут описаны трудности с которыми авторы столкнулись и описаны опробованные приёмы решения.
Семён Григорьев
Григорьев Семён Вячеславович. В 2012 году закончил магистратуру на Математико-Механическом факультете СПбГУ по специальности “Информационные технологии”. Разработчик компании ЗАО “Ланит-Терком” с 5-ти летним стажем. Активно совмещаю работу и исследовательскую деятельность.
Со-автор: Яков Кириленко