sql >> データベース >  >> RDS >> Sqlserver

mssql で複数レベルの関連テーブルをコピーする

    PK が IDENTITY の場合 列、MERGE を含む手法を使用できます この質問 .

    プロセス全体をスクリプト化する方法は次のとおりです。

    DECLARE @OldID int, @NewID int;
    SET @OldID = some_value;
    
    DECLARE @TwoMapping TABLE (OldID int, NewID int);
    DECLARE @ThreeMapping TABLE (OldID int, NewID int);
    
    INSERT INTO One
    SELECT columns
    FROM One
    WHERE OneID = @OldID;
    SET @NewID = SCOPE_IDENTITY();
    /*
    That one was simple: one row is copied, so just reading SCOPE_IDENTITY()
    after the INSERT. The actual mapping technique starts at this point.
    */
    
    MERGE Two tgt
    USING (
      SELECT
        @NewID AS OneID,
        other columns
      FROM Two t
      WHERE OneID = @OldID
    ) src
    ON 0 = 1
    WHEN NOT MATCHED THEN
      INSERT (columns) VALUES (src.columns)
    OUTPUT src.TwoID, INSERTED.TwoID INTO @TwoMapping (OldID, NewID);
    /*
    As you can see, MERGE allows us to reference the source table in the
    OUTPUT clause, in addition to the pseudo-tables INSERTED and DELETED,
    and that is a great advantage over INSERT and the core of the method.
    */
      
    
    MERGE Three tgt
    USING (
      SELECT
        map.NewID AS TwoID,
        t.other columns
      FROM Three t
        INNER JOIN @TwoMapping map ON t.TwoID = map.OldID
    ) src
    ON 0 = 1
    WHEN NOT MATCHED THEN
      INSERT (columns) VALUES (src.columns)
    OUTPUT src.ThreeID, INSERTED.ThreeID INTO @ThreeMapping (OldID, NewID);
    /*
    Now that we've got a mapping table, we can easily substitute new FKs for the old
    ones with a simple join. The same is repeated once again in the following MERGE.
    */
    
    MERGE Four tgt
    USING (
      SELECT
        map.NewID AS ThreeID,
        t.columns
      FROM Four t
        INNER JOIN @ThreeMapping map ON t.ThreeID = map.OldID
    ) src
    ON 0 = 1
    WHEN NOT MATCHED THEN
      INSERT (columns) VALUES (src.columns);
    /*
    The Four table is the last one in the chain of dependencies, so the last MERGE
    has no OUTPUT clause. But if there were a Five table, we would go on like above.
    */
      

    または、おそらくカーソルを使用する必要があります。これは、SQL Server 2005 以前のバージョンでこれを行う唯一の (正気の) 方法のようです。



    1. PDOは最後に挿入されたIDを取得します

    2. 自動インクリメンタルデータベースを使用したLaravelupdateOrCreate

    3. MYSQLでの削除時に同じテーブルを更新するにはどうすればよいですか?

    4. Yiiでクエリを更新する