4
votes

Synchronisation des données entre les tables de SQL Server et Db2 - Comment supprimer des lignes

Nous avons deux bases de données une dans SQL Server et une dans DB2, nous avons un scénario dans lequel nous effectuons des insertions de données, des mises à jour et des suppressions de données dans SQL Server et en même temps, nous effectuons également des mises à jour et des suppressions d'insertions de données dans Db2.

Nous synchronisons les données dans les deux sens à l'aide de certains processus, chaque fois qu'il y a un changement de SQL Server, nous synchronisons les données vers db2 pour l'insertion, la mise à jour et la suppression, si nous avons un changement dans db2, nous synchronisons les données avec SQL Server, nous utilisons les messages IBM MQ qui nous retirons les messages de la file d'attente pour synchroniser les modifications dans les deux sens.

Tout était bon jusqu'à ce que nous ayons des problèmes de synchronisation des données de Db2 vers SQL Server, l'un de nos processus était en panne de synchronisation de db2 vers SQL Server, il y a donc un travail à la demande qui s'exécute chaque nuit qui effectuera une actualisation complète des données à partir de Db2 vers SQL Server mais nous ne faisons que Merge Update & insert, nous ne faisons pas de suppression car les données qui doivent encore être synchronisées avec db2 sont également présentes dans SQL Server, nous ne pouvons donc pas supprimer directement car les deux bases de données peuvent avoir plus ou moins d'enregistrements, donc les données sur SQL Server certaines d'entre elles sont laissées orphelines, nous avons une portée afin que les données qui sont mises à jour dans SQL Server ne puissent pas être modifiées dans db2 et vice versa.

Ma question est lorsque nous synchronisons de Db2 vers SQL Server, comment identifier les enregistrements qui ont été supprimés de db2 uniquement afin que nous puissions les supprimer de SQL Server, nous ne voulons pas supprimer les enregistrements qui sont créés dans SQL Server mais pas encore être envoyé à db2, nous avons 114 tables et nous ne pouvons pas maintenir un indicateur si c'est une option pour différencier.


2 commentaires

Il semble que vous synchronisez manuellement les mises à jour entre les systèmes, qui sont tous deux traités comme des données de base. Cela a le potentiel d'aller plus mal, franchement. Personnellement, je ferais probablement un côté "maître", et configurerais la réplication , puis demanderais à l'autre côté de pousser les mises à jour vers le maître via les déclencheurs INSTEAD OF , et attendrais que les données soient filtrées vers la table synchronisée, qui devrait être plus stable .


Nous avons deux bases de données une dans SQL Server et Db2 (Mainframes) existant qui est un système hérité. Comment pouvons-nous créer une réplication pour deux bases de données différentes dans SQL & Db2?, Donc pour résoudre ce problème, nous envoyons des messages IBM MQ et chaque partie consomme ces messages pour synchroniser les modifications dans les deux systèmes.DB2 dans une certaine mesure est comme maître et SQL a moins de tables qui sont étendues pour la phase 1, le processus de chargement des modifications de db2 à sql est interrompu et nous avons à la demande qui actualise la base de données complète en copiant les tables de transfert vers SQL, ici nous ne pouvons pas supprimer en sql car nous pourrions perdre données qui doivent encore être envoyées à DB2, comment?


4 Réponses :


2
votes

Le suivi des modifications côté serveur SQL peut être une option viable (à condition que toutes les tables que vous souhaitez synchroniser / "supprimer de" aient une clé primaire).

Avec CT, vous pouvez suivre les lignes, pour chaque table, qui ont été créées du côté du serveur SQL depuis la dernière synchronisation du serveur SQL vers db2. Ces lignes ne doivent pas encore être supprimées:

DELETE 
FROM SQL_SERVER_TABLE
WHERE
  NOT EXISTS(SELECT * FROM CHANGETABLE())
  AND NOT EXISTS(SELECT * FROM DB2_staging)


0 commentaires

2
votes

Je connecterais SQL à DB2 via des serveurs liés (plus ici: https://docs.microsoft.com/fr-fr/sql/relational-databases/system-stored-procedures/sp-addlinkedserver-transact-sql?view=sql -server-ver15 ), puis effectuez des requêtes pour savoir quel enregistrement manque des deux côtés. Ceci peut être accompli avec OPENQUERY. Vous pouvez faire quelque chose comme ça:

DECLARE @TABLENAME nvarchar(200);
DECLARE TABLE_CUR CURSOR FOR
     SELECT TABLE_NAME FROM YourDatabaseName.INFORMATION_SCHEMA.TABLES;

OPEN TABLE_CUR 
FETCH NEXT FROM TABLE_CUR INTO @TABLENAME;

WHILE @@FETCH_STATUS = 0  
BEGIN  
    DECLARE @Query nvarchar(MAX);
    SET @Query =  'SELECT * FROM OPENQUERY(YOURDB2SERVER, ''SELECT * 
                   FROM '+ @TABLENAME + ' '')
                   EXCEPT 
                   SELECT * FROM '+ @TABLENAME 

    -- Don't forget the double '' for openquery

    EXEC sp_executeSQL @Query;

    SET @Query =  'SELECT * FROM '+ @TABLENAME + ' 
                   EXCEPT
                   SELECT * FROM OPENQUERY(YOURDB2SERVER, ''SELECT * 
                   FROM '+ @TABLENAME + ' '')'
    -- Don't forget the double '' for openquery

    EXEC sp_executeSQL @Query;
END
CLOSE TABLE_CUR;  
DEALLOCATE TABLE_CUR;  

Et puis la même chose inversée:

SELECT * FROM OPENQUERY(YOURDB2SERVER, 'SELECT * FROM YourDB2Table')
EXCEPT 
SELECT * FROM YourSqlTable

Vous pouvez ensuite envoyer les enregistrements sur le bon serveur.

Si vous avez beaucoup de tables à comparer, vous pouvez écrire ces requêtes avec du SQL dynamique

SELECT * FROM YourSqlTable
EXCEPT 
SELECT * FROM OPENQUERY(YOURDB2SERVER, 'SELECT * FROM YourDB2Table')


0 commentaires

3
votes

Lorsque vous avez dit que vous synchronisez des données entre MS SQL Server et DB2 Server, comment capturez-vous les modifications? Si vous utilisez un outil CDC (IDR, GoldenGate, Informatica), ces outils vous permettent de détecter les conflits afin que vous puissiez décider quels enregistrements conserver ou supprimer.

Si vous capturez vos modifications par un développement interne (déclencheurs ou votre propre outil de récupération de journaux), vous devez conserver au moins le type d'opération et l'horodatage dans votre ensemble de données de modification temporaire, afin de pouvoir reconnaître l'opération.

Si vous comparez les tables et gérez les modifications, vous ne pourrez pas reconnaître si les colonnes manquantes du côté DB2 représentent les lignes supprimées du côté DB2 ou les lignes ajoutées du côté SQL ... Mais vous pouvez résoudre ce problème en développant un changer le mécanisme de capture des données.


0 commentaires

0
votes

Merci pour les suggestions, je n'utilise pas CDC, mais je conserve les modifications dans une table LOG qui doivent encore être synchronisées avec DB2.

 MERGE INTO [dbo].[LocationType] AS TGT
  USING [IGP].[LocationType] AS SRC
  ON TGT.[LocationTypeCode] = SRC.[LocationTypeCode]
  WHEN MATCHED  AND (EXISTS 
  (SELECT TGT.[Description] EXCEPT SELECT SRC.[Description]))  
  THEN
    UPDATE SET TGT.[LocationTypeCode] = SRC.[LocationTypeCode], 
    TGT.[Description] = SRC.[Description]
  WHEN NOT MATCHED THEN
  INSERT([LocationTypeCode], [Description]) 
  VALUES([LocationTypeCode], [Description]) 
  WHEN NOT MATCHED BY SOURCE 
  AND (EXISTS (SELECT TGT.[LocationTypeCode] 
      EXCEPT SELECT [LocationTypeCode] FROM #locationType)) THEN DELETE;

J'insère d'abord les données de la table de journal qui doivent encore être synchronisées avec DB2 dans la table temporaire #locationType et je les supprime d'IGP (données de base Db2 de préparation) afin que les mises à jour et les suppressions ne soient pas remplacées par les données de la table de transfert IGP qui sont Db2 données de base.

Maintenant, je dois m'occuper des insertions qui n'existent pas dans Db2 et là dans le serveur SQL, mais ce n'est pas synchronisé à partir de la table du journal, je ne devrais pas les supprimer car ce serait une perte de données, donc j'utilise la requête de fusion ci-dessous

DELETE TGT
   FROM [IGP].[LocationType] AS TGT
   INNER JOIN #locationType SRC ON 
   TGT.[LocationTypeCode] = SRC.[LocationTypeCode];


0 commentaires