实现对Oracle

时间:2018-05-09 12:52:56

标签: sql oracle migration

我们有一个使用Oracle数据库的Java系统。我以前有使用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专家从一开始就知道如何做到这一点。

1 个答案:

答案 0 :(得分:1)

有一些注释可能很有用:

可以创建shell脚本来支持数据库基线 baseline 是新开发周期开始时的数据库/架构状态。例如,它可以是scrum sprint开始时的数据库状态。可以使用oracle Data Pump实用程序(dbexpdpimp)。这些脚本应执行以下任务:将模式导出到平面文件(例如dev_schema_v2.4),删除模式中的所有对象,将转储文件导入指定的模式等。

使用这些脚本可以帮助回滚,因为您只需要清理架构,导入其中一个基线文件并应用上次迁移脚本。 Flyway 可用于应用迁移脚本。