Comment copyr des loggings de tables liées entre elles vers une autre dans une database différente?

J'ai 3 tables qui sont interconnectées entre elles. La design des tables sont comme ci-dessous.

  • Premier (PK: FirstID, vchar: Name, int: Year)
  • Deuxième (PK: SecondID, FK: FirstID, int: Jour, int: Mois)
  • Troisième (PK: ThirdID, FK: SecondID, int: Vitesse, vchar: Remarque)

J'essaie de copyr des loggings à partir de 3 tables liées entre la database A et la database B. Ainsi, mon Transact-SQL ressemble à ceci:

INSERT INTO First (Name, Year) SELECT Name, Year FROM DB_A.dbo.First WHERE Year >= 1992 INSERT INTO Second (FirstID, Day, Month) SELECT FirstID, Day, Month FROM DB_A.dbo.Second S INNER JOIN DB_A.dbo.First F ON S.FirstID = F.FirstID WHERE Month > 6 INSERT INTO Third (SecondID, Speed, Remark) SELECT SecondID, Speed, Remark FROM DB_A.dbo.Third T INNER JOIN DB_A.dbo.Second S ON T.SecondID = S.SecondID INNER JOIN DB_A.dbo.First F ON F.FirstID = S.FirstID WHERE Remark <> NULL 

Ces instructions fonctionnent bien et bien jusqu'à ce que la position de départ de First.FirstID dans la database A et B ne soit plus la même, car les trois tables de la database B sont vides. Par conséquent, la contrainte sur l'erreur foreign_key est produite.

Solutions possibles

  1. Réutilisez old First.FirstID L'une des solutions que j'ai trouvées consiste à réutiliser l'ancien First.FirstID de la database A. Cela peut être fait en réglant SET IDENTITY_INSERT TableName ON juste avant l' insert into TableName et en incluant le TableName.TableNameID dans le insert une déclaration. Cependant, je suis conseillé de ne pas le faire par mes collègues.

  2. Écrasez Second.FirstID avec new First.FirstID et par la suite, Third.SecondID avec le second Second.SecondID J'essaie d'appliquer cette solution en utilisant les variables OUTPUT et TABLE en affichant tout First.FirstID dans une variable de table temporaire et en les associant à la table Deuxième semblable à cette réponse Cependant, je suis coincé sur la façon d'associer et de replace le Second.FirstIDs avec les ID corrects dans la table temporaire. Une réponse sur la façon de le faire serait également acceptée comme réponse à cette question .

  3. Utiliser la solution n ° 1 et mettre à jour les keys primaires et étrangères en utilisant UPDATE CASCADE . J'ai juste eu cette idée mais j'ai le sentiment que ce sera très fastidieux. Plus de search doit être faite mais s'il y a une réponse qui montre comment implémenter ceci avec succès, alors j'accepterai cette réponse.

Alors, comment puis-je copyr des loggings à partir de 3 tables inter-liées à 3 autres tables similaires mais des keys primaires différentes? Y a-t-il de meilleures solutions que celles proposées ci-dessus?

Vous pouvez utiliser la clause OUTPUT .

 CREATE TABLE #First (NewId INT PRIMARY KEY, OldId INT) INSERT INTO First ( Name, Year, OldId -- Added new column ) OUTPUT Inserted.FirstID, Inserted.OldId INTO #First SELECT Name, Year, FirstID -- Old Id to OldId Column FROM DB_A.dbo.First WHERE Year >= 1992 

Deuxième table

 CREATE TABLE #Second (NewId INT PRIMARY KEY, OldId INT) INSERT INTO Second ( FirstID, Day, Month, OldId -- Added new column ) OUTPUT Inserted.SecondID, Inserted.OldId INTO #Second SELECT OF.NewId, --FirstID Day, Month, SecondID FROM DB_A.dbo.Second S INNER JOIN DB_A.dbo.First F ON S.FirstID = F.FirstID INNER JOIN #First OF ON F.FirstId = OF.OldId -- Old ids here WHERE Month > 6 

Le dernier

 INSERT INTO Third ( SecondID, Speed, Remark ) SELECT OS.NewId, -- SecondID Speed, Remark FROM DB_A.dbo.Third T INNER JOIN DB_A.dbo.Second S ON T.SecondID = S.SecondID INNER JOIN DB_A.dbo.First F ON F.FirstID = S.FirstID INNER JOIN #Second OS ON S.SecondID = OS.OldId WHERE Remark <> NULL 

Première solution

Utiliser MERGE et OUTPUT set

OUTPUT combiné avec la fonction MERGE a la capacité de récupérer les anciennes keys primaires avant de les insert dans la table.

Deuxième solution

Remarque: cette solution fonctionne uniquement si vous êtes sûr que vous avez une autre colonne dont les valeurs sont uniques dans la table en dehors de la key primaire de la table.

Vous pouvez utiliser cette colonne comme lien entre la table de la database source et sa table sœur dans la database cible. Le code ci-dessous est un exemple prenant en count que First.Name a des valeurs uniques lorsque month> 6.

 -- no changes to insert code in First table INSERT INTO First (Name, Year) SELECT Name, Year FROM DB_A.dbo.First WHERE Year >= 1992 INSERT INTO Second (FirstID, Day, Month) SELECT CurrentF.FirstID, Day, Month -- 2. Use the FirstID that has been input in First table FROM DB_A.dbo.Second S INNER JOIN DB_A.dbo.First F ON S.FirstID = F.FirstID INNER JOIN First CurrentF ON CurrentF.Name = F.Name -- 1. Join Name as a link WHERE Month > 6 INSERT INTO Third (SecondID, Speed, Remark) SELECT CurrentS.SecondID, Speed, Remark --5. Get the proper SecondID FROM DB_A.dbo.Third T INNER JOIN DB_A.dbo.Second S ON T.SecondID = S.SecondID INNER JOIN DB_A.dbo.First F ON F.FirstID = S.FirstID INNER JOIN First CurrentF ON CurrentF.Name = F.Name INNER JOIN -- 3. Join using Name as Link Second CurrentS ON CurrentS.FirstID= CurrentF.FirstID -- 4. Link Second and First table to get the proper SecondID. WHERE Remark <> NULL