2017-05-29 64 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