Bonjour,
J’essaie de paramétrer une réplication transactionnelle sur une table (pour l’exemple) entre deux bases de données qui ont exactement la même structure (tables, procédures stockées, vues etc.).
Les données doivent être répliquées uniquement de l’éditeur vers l’abonnée.
Cependant l’abonné peut avoir plus des tuples en plus dans sa table.
Par ailleurs, j’ai comme contrainte que je ne peux pas modifier la structure de ma table (ajout de champ, modification de contrainte etc.).
Voici la structure de ma table exemple :
Remarque :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10 CREATE TABLE ADM.TABLE_TEST( ID_TABLE_TEST numeric(10, 0) NOT NULL, NOM_TABLE_TEST nvarchar(50) NULL, CODE_TABLE_TEST nvarchar(50) NULL, REPLIQUE numeric(1, 0) NULL, CONSTRAINT PK_ADM.TABLE_TEST PRIMARY KEY CLUSTERED ( ID_TABLE_TEST ASC ) ON PRIMARY ) ON PRIMARY
- ID_TABLE_TEST n’est pas un identifiant auto incrémenté.
- CODE_TABLE_TEST n’est pas une clef primaire, mais est unique dans la table (règle de gestion).
- REPLIQUE est l’équivalent d’un booléen qui me permet de sélectionner les données à répliquer si sa valeur vaut 1 (dans tous les autres cas on ne réplique pas la ligne).
Chez l’éditeur j’ai ces données dans la table :
1, ‘Lundi’, ‘LUN’, 0
2, ‘Mardi’, ‘MAR’, 1
Chez l’abonnée j’ai ces données dans la table :
1, ‘Vendredi’, ‘VEN’, 0
2, ‘Samedi’, ‘SAM’, 0
Mon but à l’issue de la réplication est d’obtenir chez l’abonné ces données :
1, ‘Vendredi’, ‘VEN’, 0
2, ‘Samedi’, ‘SAM’, 0
3, ‘Mardi’, ‘MAR’, 1
Le problème est que si je laisse la configuration par défaut de la réplication, l’éditeur va essayer d’insérer dans la table de l’abonnée la ligne :
2, ‘Mardi’, ‘MAR’, 1
Ce qui déclenche une exception de violation de clef primaire étant donné que dans la table de l’abonné, il existe déjà une ligne avec l’ID_TABLE_TEST à 2.
Je décide donc de créer une procédure stockée personnalisée pour l’insertion de donnée que je veux substituer à la procédure par défaut.
Voici son contenu :
La procédure est présente sur l’éditeur et sur l’abonnée.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28 CREATE PROCEDURE ADM.INSERT_TABLE_TEST @c1 numeric(10,0), @c2 nvarchar(50), @c2 nvarchar(50), @c4 numeric(1,0) AS BEGIN /*Test d'unicité sur le code_table_test : on insère la donnée que s'il n'existe pas d'élément avec ce code dans la table.*/ if not exists(select * from ADM.TABLE_TEST where CODE_TABLE_TEST =@c3) BEGIN /*On calcul le prochain identifiant*/ declare myCursor CURSOR FOR select isnull(max(ID_TABLE_TEST),0)+1 from ADM.TABLE_TEST open myCursor; FETCH NEXT FROM myCursor INTO @c1; close myCursor; DEALLOCATE myCursor; /*On insère le nouveau tuple dans la table*/ insert into ADM.TABLE_TEST( ID_TABLE_TEST, NOM_TABLE_TEST, CODE_TABLE_TEST, REPLIQUE ) values ( @c1, @c2, @c3, @c4 ) END END
Je configure ensuite ma publication (sous SQL Server Entreprise Manager v8.0) par le wizard.
Je sélectionne l’article ADM.TABLE_TEST.
Je filtre les lignes de la table à l’aide de cette clause de filtre :
Puis dans les propriétés de l’article je coche la case ‘Remplacer les commandes INSERT par cet appel de procédure stockée :’.
Code : Sélectionner tout - Visualiser dans une fenêtre à part SELECT <colonnes_publiées> FROM <<TABLE>> WHERE <<TABLE>>.REPLIQUE=1
Et dans la zone de texte juste à coté je saisi : ‘CALL ADM.INSERT_TABLE_TEST’ soit le nom de ma procédure stockée personnalisée.
Je décoche la case ‘Créer les procédures stockées au cours de la synchronisation initiale des abonnements’ étant donnée que mes bases de données éditeur et abonné possèdent déjà la procédure stockée.
Enfin à lorsque l’on me demande ‘Si la table de donnée « TABLE_TEST » existe chez l’abonnée’ je sélectionne ‘Conserver la table existante inchangée’ au lieu de ‘Supprimer (à l’aide de DROP) la table existante et la recréer' sélectionné par défaut.
A partir d’ici deux cas se présentent :
1er cas :
Je défini un nouvel abonnement où je précise à la question ‘Lors de la création de l’abonnement, Microsoft SQL Server doit-t-il initialiser le schéma et les données de l’abonnée ?’ dans l’onglet ‘Initialiser l’abonnement’ :
‘Non, l’abonné dispose déjà du schéma et des données’.
Je lance ensuite l’agent et la capture, puis la réplication.
Et j’obtiens le message d’erreur suivant :
‘Le processus n'a pas pu effectuer de copie en bloc dans la table : « "ADM"."TABLE_TEST" ».
Violation de la contrainte PRIMARY KEY 'PK_ADM.TABLE_TEST'. Impossible d'insérer une clé en double dans l'objet 'TABLE_TEST'.
(Source : <MON_SEVEUR> (Source de données) ; Numéro d'erreur : 2627)’
2ème cas :
Je supprime l’abonnement précédent et je défini un nouvel abonnement où je précise à la question ‘Lors de la création de l’abonnement, Microsoft SQL Server doit-t-il initialiser le schéma et les données de l’abonnée ?’ dans l’onglet ‘Initialiser l’abonnement’ :
‘Oui, initialiser le schéma et les données’.
Je lance ensuite l’agent et la capture, qui me dit ‘Aucune capture instantanée n’a été générée car aucun abonnement ne nécessitait’.
Je lance alors la réplication.
Et j’obtiens le message suivant : ‘Opération réussie’, ‘Aucune transaction répliquée n’est disponible’.
Et rien ne se passe au niveau de la base de donnée.
Merci pour votre aide par avance.
Partager