2017-05-29 96 views
0

我正在研究管理Oracle数据库中的参考数据的最佳方法。我们在源代码控制中保留参考数据,并在部署过程中更新参考表。Oracle - Flyway数据库参考数据

我们使用Flyway来部署我们的更改,并且我们为每个参考表设置一个可重复的脚本,以确保数据在每次部署后都是最新的。

在SQL服务器数据库中,我们创建了一个SQL脚本,该脚本将inserts语句包含到给定表的引用数据的变量表中,并使用MERGE语句插入/更新/删除实际表。这样我们可以管理每个分支的参考数据。

SQL Server示例

-- temporary table to hold all data 
DECLARE @product_type TABLE 
(
    [id] varchar(25) 
    ,[name] varchar(50) 
) 

INSERT @product_type ([id], [name]) VALUES ('1', 'Product 1') 
INSERT @product_type ([id], [name]) VALUES ('2', 'Product 2') 
INSERT @product_type ([id], [name]) VALUES ('3', 'Product 3') 

-- merge changes into table 
MERGE [PRODUCT_TYPE] AS t 
USING @product_type AS s 
ON  (t.[id] = s.[id]) 
WHEN MATCHED 
THEN UPDATE 
     SET t.[name] = s.[name] 
WHEN NOT MATCHED BY TARGET 
THEN INSERT ([id], [name]) 
     VALUES (s.[id], s.[name]); 

--delete removed product type 
DELETE [PRODUCT_TYPE] 
WHERE id NOT IN (SELECT id FROM @product_type) 

因为在Oracle中,你不能真正创建变量表,甚至短暂的临时表我不知道是什么做的比创建临时表类似的其它东西的正确方法和然后在最后删除它。

Oracle示例

BEGIN 
    EXECUTE IMMEDIATE 'DROP TABLE TMP__product_type'; 
EXCEPTION 
    WHEN OTHERS THEN 
     IF SQLCODE != -942 THEN 
     RAISE; 
     END IF; 
END; 
/

CREATE TABLE TMP__product_type 
(
    id VARCHAR2(25 BYTE) NOT NULL 
, name VARCHAR2(50 BYTE) 
); 


INSERT INTO TMP__product_type VALUES ('1,', 'Product 1'); 
INSERT INTO TMP__product_type VALUES ('2,', 'Product 2'); 
INSERT INTO TMP__product_type VALUES ('3,', 'Product 3'); 

MERGE INTO product_type T 
    USING (SELECT id, name FROM TMP__product_type s) S 
    ON (T.id = S.id) 
    WHEN MATCHED THEN 
    UPDATE SET T.name = S.name 
    WHEN NOT MATCHED THEN 
    INSERT (T.id, T.name)VALUES (S.id, S.name); 

DELETE FROM product_type T WHERE NOT EXISTS (SELECT s.name FROM TMP__product_type s WHERE s.name = t.name); 


BEGIN 
    EXECUTE IMMEDIATE 'DROP TABLE TMP__product_type'; 
EXCEPTION 
    WHEN OTHERS THEN 
     IF SQLCODE != -942 THEN 
     RAISE; 
     END IF; 
END; 
/

任何建议都欢迎。

回答

0

将SQL Server方法转换为Oracle实际上很简单。使用DUAL模仿内存表:

MERGE INTO product_type T 
    USING (select '1' as id, 'Product 1' as name from dual union all 
      select '2' as id, 'Product 2' as name from dual union all 
      select '3' as id, 'Product 3'as name from dual) S 
    ON (T.id = S.id) 
    WHEN MATCHED THEN 
    UPDATE SET T.name = S.name 
    WHEN NOT MATCHED THEN 
    INSERT (T.id, T.name)VALUES (S.id, S.name); 

这不处理DELETE。当然,你知道你自己的过程,但它似乎来处理,这将是具有明确删除的最佳方式:

delete from product_type T 
where T.id in ('4', '5'); 
+0

我宁愿一个解决方案,我没有跟踪单独删除,因为这将让困难时多开发者参与其中。 –

+0

目前,您正在通过从记录集中省略而隐式跟踪删除。不知道为什么这更容易,但正如我所说,你知道你自己的过程。 – APC