8

ドナー テーブルのデータを 2 つの宛先テーブルにマージする必要があります。構造は以下の通りです。トレース テーブルに projid が見つからない場合は、コンポーネント テーブルに新しいコンポーネントを作成し、新しい ID を使用してトレース テーブルに挿入する必要があります。また、ドナー テーブルに存在しなくなった項目については、トレース テーブルの「アクティブ」列を 0 に設定する必要があります。1 つのマージ ステートメントでこれを達成できますか?

ドナー表

projid      | datestamp    | Ownerid
-------------------------------------------------
c_abc        1-jan-2013      name1
c_def        2-jan-2013      name3
c_ghi        3-jan-2013      name4

トレース テーブル

compid      |projid     |active | ... 
-----------------------------------------------
123           c_abc      1
124           c_xyz      1
125           c_def      1

コンポーネント テーブル

compid      |ownerid
-------------------------
123      name1
124      name2
125      name3

マージ後の出力テーブル:

コンポーネント テーブル

compid      |ownerid
-------------------------
123      name1
124      name2
125      name3
126      name4

トレース テーブル

compid      |projid     |active | ... 
-----------------------------------------------
123          c_abc       1
124          c_xyz       0
125          c_def       1
126          c_ghi       1
4

1 に答える 1

5

理論的には、これを単一のステートメントで行うための解決策があるはずですが、これまでのところ見つけることができませんでした。*

MERGE2 つのステートメントを使用して実行する方法を次に示します。

WITH CTE_trgt AS 
(
    SELECT c.compid, c.ownerid, t.projid, t.active 
    FROM component c
    INNER JOIN trace t ON c.compid = t.compid
)
MERGE CTE_trgt t
USING Donor s
ON t.projid = s.projid
WHEN NOT MATCHED BY TARGET
    THEN INSERT (ownerid)
    VALUES (s.ownerid)
OUTPUT
    INSERTED.compid, s.projid, 1 INTO trace;


MERGE trace t
USING Donor s
ON t.projid = s.projid
WHEN NOT MATCHED BY SOURCE 
    THEN UPDATE SET t.active = 0;

SQLFiddle デモ


* アクティブな列を更新する部分:

WHEN NOT MATCHED BY SOURCE 
    THEN UPDATE SET t.active = 0

すべての操作に対して単一のマージステートメントを作成する上部のクエリに収まるはずですが、エラーがスローされます。

変更が複数のベース テーブルに影響するため、ビューまたは関数 't' は更新できません

明らかに単一の列であっても、通常の非マージ更新は正常に機能します。誰かがこれの理由や回避策を知っているかもしれません。

于 2013-08-09T09:26:43.127 に答える