У нас есть система Java, которая использует базу данных Oracle. У меня был предыдущий опыт работы с Laravel, и мне очень понравилась идея сценариев миграции, и я хотел внедрить нечто подобное в нашей системе (но пока без поддержки отката миграции).
По сути, это будет основано на таблице migrations
, которая содержит уникальное имя конкретного сценария миграции, а также дату события вставки (только для административных целей). Каждый сценарий миграции будет основан на шаблоне, который содержит код переноса для первой проверки существования его имени в таблице migrations
и пропускает сценарий, если имя найдено. В конце успешного выполнения скрипт вставляет свое имя в таблицу migrations
.
Я новичок в Oracle и сомневаюсь в правильной реализации этой функции.
Мне нужно будет выполнить каждый сценарий миграции в отдельной транзакции и безопасно откатить всю миграцию (включая изменения схемы) в случае сбоя.
Один файл SQL будет содержать несколько сценариев миграции.
Я не хочу изобретать велосипед - может быть, это уже сделано, и в Github или Gist есть фрагмент кода? Но я не смог его найти.
Вот псевдокод, который я хотел бы превратить в Oracle-совместимый SQL:
START TRANSACTION
SET @SCRIPT_NAME = 'myUniqueMigrationScript'
IF NOT EXISTS (SELECT 1 FROM migrations WHERE migrations.name = @SCRIPT_NAME)
BEGIN
TRY
BEGIN
-- the migration itself - create/update/insert records, modify schema etc.
INSERT INTO migrations VALUES (name, created_at) VALUES (@SCRIPT_NAME, CURRENT_TIMESTAMP)
COMMIT TRANSACTION
END
CATCH error
BEGIN
ROLLBACK TRANSACTION
PRINT 'Error while executing migration ' + @SCRIPT_NAME + ': ' + error.message
END
ELSE
BEGIN
PRINT 'Skipping migration ' + @SCRIPT_NAME + ' - it had been already applied.'
END
-- possibly other similar wrapped script pieces follow in the same file
Возможно ли это вообще в Oracle? Каковы возможные предостережения?
Я видел нечто подобное для Microsoft SQL Server, и у него было много предостережений для правильной обработки исключений и отката (правильный порядок операторов GO, BEGIN CATCH, IF @@ TRANCOUNT, небезопасное поведение set xact_abort, @@ ERROR и т. Д. специфические синтаксические элементы).
Я бы хотел избежать этих нюансов для Oracle - я уверен, что специалисты Oracle знают, как это сделать с самого начала.