Sqlserver
 sql >> Baza danych >  >> RDS >> Sqlserver

Kopiowanie wielopoziomowych powiązanych tabel w mssql

Jeśli Twoje PK to IDENTITY kolumn, możesz użyć techniki wykorzystującej MERGE który jest opisany w to pytanie .

Oto jak cały proces może być skryptowany:

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.
*/

Alternatywnie prawdopodobnie będziesz musiał użyć kursorów, co wydaje się być jedynym (rozsądnym) sposobem na zrobienie tego w SQL Server 2005 i wcześniejszych wersjach.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Co naprawdę robi metoda Statement.setFetchSize(nSize) w sterowniku SQL Server JDBC?

  2. Dlaczego opcja indeksowania pełnotekstowego jest wyszarzona?

  3. Jak skonfigurować pyodbc, aby poprawnie akceptował ciągi z SQL Server przy użyciu freeTDS i unixODBC?

  4. Biblioteka natywna sqljdbc_auth.dll została już załadowana w innym programie ładującym klas

  5. Automatycznie generuj typ tabeli zdefiniowany przez użytkownika, który pasuje do istniejącej tabeli