2017-05-29 17 views
0

参照データをOracleデータベースで管理する最善の方法を検討しています。参照データはソース管理で保持し、参照テーブルは展開プロセス中に更新されます。Oracle - Flyway DB参照データ

私たちは変更を展開するためにFlywayを使用し、各展開後にデータが最新であることを確認するために、参照テーブルごとに反復可能なスクリプトをセットアップしました。

SQLサーバーデータベースでは、insertsステートメントを含むSQLスクリプトを、特定のテーブルの参照データの可変テーブルに作成し、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サンプル

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に変換するのはかなり簡単です。

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を処理しません。これは、DUALを使用してメモリ内の表を模倣します。もちろん、あなたがあなた自身のプロセスを知っているが、その、これは明示的に削除してだろう処理するための最良の方法と思われる:

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

私は時に複数のが困難になるだろうとして、別途、削除を追跡する必要はありませんソリューションを好むだろう開発者が関与しています。 –

+0

現在、レコードセットからの省略によって暗黙的に削除を追跡しています。なぜそれが簡単なのか分かりませんが、私が言ったように、あなたは自分のプロセスを知っています。 – APC