Mim

Select * from Seb where Sujets in (SQL Server 2008, ADO.NET, Visual Studio 2008)

octobre 2009 - Messages

SQL SERVER Replication rowguid, generation triggers

Voilà un truc tout bête, à connaitre quand on met en place une réplication par fusion.

Symptôme : Je crée une réplication sur un serveur de pré prod, à partir d’un script d’une réplication qui fonctionne sur un serveur de dev.

LE script, généré par le wizard donc, ressemble à quelque chose comme ça :

   1: use [TestDB]
   2: exec sp_replicationdboption @dbname = N'TestDB', @optname = N'merge publish', @value = N'true'
   3: GO
   4: -- Adding the merge publication
   5: use [TestDB]
   6: exec sp_addmergepublication @publication = N'replTest', 
   7:     @description = N'Merge publication of database ''TestDB'' from Publisher ''MIM\SQL2008''.', @sync_mode = N'character', @retention = 14,
   8:     @allow_push = N'true', @allow_pull = N'true', @allow_anonymous = N'true', @enabled_for_internet = N'false', @snapshot_in_defaultfolder = N'true', 
   9:     @compress_snapshot = N'false', @ftp_port = 21, @ftp_subdirectory = N'ftp', @ftp_login = N'anonymous', @allow_subscription_copy = N'false', 
  10:     @add_to_active_directory = N'false', @dynamic_filters = N'false', @conflict_retention = 14, @keep_partition_changes = N'false', 
  11:     @allow_synctoalternate = N'false', @max_concurrent_merge = 0, @max_concurrent_dynamic_snapshots = 0, @use_partition_groups = null, 
  12:     @publication_compatibility_level = N'90RTM', @replicate_ddl = 1, @allow_subscriber_initiated_snapshot = N'false', @allow_web_synchronization = N'true', 
  13:     @allow_partition_realignment = N'true', @retention_period_unit = N'days', @conflict_logging = N'both', @automatic_reinitialization_policy = 0
  14: GO
  15:  
  16:  
  17: exec sp_addpublication_snapshot @publication = N'replTest', @frequency_type = 4, @frequency_interval = 14, @frequency_relative_interval = 1, 
  18:     @frequency_recurrence_factor = 0, @frequency_subday = 1, @frequency_subday_interval = 5, @active_start_time_of_day = 500, 
  19:     @active_end_time_of_day = 235959, @active_start_date = 0, @active_end_date = 0, 
  20:     @job_login = N'MIM\ReplicationAdmin', @job_password = 'MY_PASSWORD_', @publisher_security_mode = 1
  21:  
  22:  
  23: use [TestDB]
  24: exec sp_addmergearticle @publication = N'replTest', @article = N'Table1', @source_owner = N'dbo', @source_object = N'Table1', 
  25: @type = N'table', @description = null, @creation_script = null, @pre_creation_cmd = N'drop', 
  26: @schema_option = 0x000000B208034FF1, @identityrangemanagementoption = N'manual', 
  27: @force_reinit_subscription = 1, @column_tracking = N'false', @subset_filterclause = null, @vertical_partition = N'false', 
  28: @verify_resolver_signature = 1, @allow_interactive_resolver = N'false', @fast_multicol_updateproc = N'true', @check_permissions = 0,
  29:  @subscriber_upload_options = 0, @delete_tracking = N'true', @compensate_for_errors = N'false', @stream_blob_columns = N'false', @partition_options = 0
  30: GO

Bref, rien de bien extraordinaire…

Je l’exécute, classique, tout se passe bien et je me dis “tiens allons vérifier si ma table”

Et là c’est le drame, ma table ne contient, ni rowguid, ni triggers !

image

Le script serait 'il donc moisi ???

Et bien pas du tout !

Les triggers, et autres colonne supplémentaire, bref tous les composants nécessaires à la table, ne seront générés que lors de la création du premier snapshot !

Après lancement du Snapshot Agent :

image

image

Voici l’état de ma table

image

Alors la question simple : Pourquoi ne pas avoir créé les triggers avant ?

Tout simplement, pour des raisons de performances.

Inutile de créer des colonnes, et triggers supplémentaires (et autre procédures stockées systèmes etc …) alors qu’aucun snapshot n’a été généré, aucun abonné n’a demandé à récupérer des informations de la table, bref, aucun intérêt !

Bref, juste une question de gain de performance, bien pensé en somme !

Microsoft Sync Framework V2.0

Et voilà la version RTM de Sync Framework 2.0 est sortie.

Vue d'ensemble de Sync Framework 2.0
Sync Framework 2.0 développe les fonctions offertes par Sync Framework 1.0 :

  • Ajoute des fonctionnalités qui répondent aux besoins de nouveaux scénarios ou de scénarios qui étaient difficiles à prendre en charge.
  • Facilite le travail lié au développement de fournisseurs.
  • Prend en charge davantage de sources de données avec de nouveaux fournisseurs intégrés.

Les principales nouvelles fonctionnalités et améliorations incluses dans Sync Framework 2.0 sont les suivantes :
Dans les composants principaux :
  • Fournisseurs simples : facilitent le travail lié au développement de fournisseurs, particulièrement lorsque la source de données a très peu de fonctions liées à la synchronisation, par exemple le suivi des modifications.
  • Filtrage flexible : les filtres d'unité de modification et les filtres personnalisés ont été ajoutés aux composants de fournisseurs personnalisés. Ces filtres, en plus des filtres d'élément de Sync Framework 1.0, vous permettent de filtrer vos données de la façon qui vous convient le mieux. 
  • Gestion des conflits améliorée : d'autres scénarios de conflits sont pris en charge, tels que le signalement des conflits de contraintes, la gestion des conflits enregistrés et la résolution des conflits à l'aide d'une stratégie de type « le dernier enregistreur gagne ».
  • Conversion de données entre des fournisseurs : dans certains scénarios, les fournisseurs de synchronisation synchronisent le même type de données (par exemple, les données de vente), mais les formats de données requis par chaque fournisseur peuvent être différents. Pour répondre aux besoins de ce scénario, Sync Framework vous permet d'implémenter des interfaces qui convertissent les données au format requis par chaque fournisseur.
  • Service d'application de modifications : augmente la souplesse et l'utilité du composant applicateur de modifications de Sync Framework.
  • Suivi : vous permet d'effectuer le suivi de l'exécution de plusieurs composants, ce qui s'avère utile pendant le débogage d'applications. 

Dans les fournisseurs de bases de données :
  • Nouveaux fournisseurs de bases de données (SQL Server et SQL Server Compact) : permettent une synchronisation d'égal à égal et hub-and-spoke pour SQL Server, SQL Server Express et SQL Server Compact. Sync Framework crée automatiquement toutes les commandes requises pour communiquer avec chaque base de données. Vous n'avez pas à écrire des requêtes de synchronisation comme vous le faites avec d'autres fournisseurs. Les fournisseurs prennent en charge les options d'initialisation flexible, le traitement par lot de modifications selon la taille des données et les tâches de maintenance, telles que le nettoyage des métadonnées et la restauration de la base de données serveur.
  • Traitement par lot basé sur la mémoire fiable : les versions précédentes de Sync Framework et Sync Services for ADO.NET ont offert un moyen aux développeurs de définir leur propre logique de traitement par lot, mais les limitations étaient nombreuses.
  • API d'approvisionnement et de gestion : les activités d'approvisionnement et d'initialisation précédemment exposées uniquement via les outils Visual Studio ont maintenant été ajoutées aux API de fournisseur de bases de données.
  • Améliorations des performances : dans cette version, les nouveaux fournisseurs de bases de données ont été méthodiquement testés dans des scénarios à grande échelle dans lesquels un serveur unique prend en charge des milliers de clients avec des centaines d'opérations de synchronisation simultanées. 

Pour plus d'informations sur les nouvelles fonctionnalités, consultez « Nouveautés dans Sync Framework 2.0 » dans la documentation qui est installée avec le Kit de développement logiciel (SDK) Sync Framework ou cliquez sur le lien Nouveautés dans Sync Framework 2.0
Output.inserted, scope_identity()

Lors des insertions en base de données, souvent la clé primaire d’une table est gérée par le moteur de base de données SQL SERVER.

Pour une clé primaire de type Identity(1,1) on voit souvent ce genre de script, qui récupère la clé générée :

INSERT INTO [ClientType] ([Libelle])   
VALUES ('Mon Type de client')
 
Select SCOPE_IDENTITY() as ClientTypeId

Le résultat sans appel : Le nouveau identifiant généré après l’insertion.

Mais que se passe t’il si la clé primaire n’est pas une clé auto incrémentée mais plutôt une clé de type uniqueidentifier ?

Voici un exemple de la table qui nous intéresse :

 
CREATE TABLE [dbo].[Test](
    [ClientId] [uniqueidentifier] NOT NULL,
    [ClientTypeId] [int] NOT NULL,
    [FirstName] [nvarchar](100) NULL,
    [LastName] [nvarchar](100) NULL,
    [Civility] [tinyint] NULL,
    [Gender] [tinyint] NULL,
    [Email] [nvarchar](250) NULL,
 CONSTRAINT [PK_Test] PRIMARY KEY CLUSTERED (    [ClientId] ASC)) 
GO
 
ALTER TABLE [dbo].[Test] 
ADD CONSTRAINT [DF_Test_ClientId]  DEFAULT (newid()) FOR [ClientId]
GO
 

Comment faire pour récupérer le GUID généré lors de l’insertion ?

Il vous suffit d’utiliser la clause Output qui permet de récupérer simplement les données insérées.

Le lien MSDN sur le sujet : Clause Output

Et voilà à quoi ressemble le script d’insertion d’une ligne avec récupération de l’identifiant de type UniqueIdentifier:

 
INSERT INTO    [Test] 
(
    [ClientTypeId] ,[FirstName] ,[LastName] ,
    [Civility]    ,[Gender] ,[Email]
)
OUTPUT inserted.ClientId
VALUES 
(
    1, 'Sébastien', 'Pertus', 
    1, 1, 'sebastien.pertus@nospam.fr'
)

Et en prime si vous utilisez SQL SERVER 2008, vous avez même droit à l’IntelliSense !!!

image 

Le résultat est, encore une fois, sans appel :)

image

A noter que l’instruction Output marche tout aussi bien avec les identifiants auto incrémentés :)

Sur ce, bonnes insertions  !!

Même pas peur !

image