Beaucoup de personnes me demandent souvent s'il existe le provider client Sync Services pour SQL Server Express.
Pour rappel, nativement, il existe le provider client Sql Server CE.
Et bien sachez qu'il existe maintenant ce fameux provider de synchronisation client, sous forme d'exemple !
Il n'est pas tout à fait complet mais reste une bonne base pour appréhender la création d'un fournisseur de synchronisation client 
Vous le trouverez ici à télécharger
Vous allez donc découvrir une classe qui hérite de ClientSyncProvider
public class SqlExpressClientSyncProvider : ClientSyncProvider
{
...
}
Cette classe doit implémenter différentes méthodes pour fonctionner, qui sont pour rappel :
-
public override SyncContext ApplyChanges(SyncGroupMetadata groupMetadata,
DataSet dataSet, SyncSession syncSession)
- Cette méthode applique les changements sur la source de données client.
-
public override SyncContext GetChanges(SyncGroupMetadata groupMetadata,
SyncSession syncSession)
-
public override SyncAnchor GetTableReceivedAnchor(string tableName)
- public override SyncAnchor GetTableSentAnchor(string tableName)
- Récupère la dernière ancre envoyée de la table paramètre
-
public override void SetTableReceivedAnchor(string tableName,
SyncAnchor anchor)
-
public override void SetTableSentAnchor(string tableName,
SyncAnchor anchor)
N'hésiter pas à récupérer ce petit exemple d'implémentation qui s'avère, au final, plutôt simple !
Rien à voir avec la choucroute, mais je rentre d'une semaine de vacances, et ben, ça fait du bien !
Evidemment, le retour aux sources est assez douloureux, surtout lorsqu'on doit dépiler les quantités de mails de retard (en virant les 90% de spam et autre bétises) et l'ensemble des flux RSS qu'on a l'habitude de parcourir !
Et justement, ce matin je suis tombé sur ce post intéressant où Pinal Dave nous explique comment récupérer la valeur courant d'un incrément automatique.
Bon pour faire simple; et comme il dit, y'a deux solutions :
1) la pas élégante (mais qui marche) :
use AdventureWorks
Select max(DatabaseLogID) From dbo.DatabaseLog as MaxErrorLog
2) la façon élégante et qui marche (aussi) :
useAdventureWorks
Dbcc CheckIdent('dbo.DatabaseLog');
Mais ... je vois un problème à la deuxième solution : Impossible de récupérer la valeur dans une application .Net ! (Là où c'est possible avec la première méthode)
heureusement, il existe une Troisième méthode qui va nous permettre de récupérer non seulement l'incrément en cours, mais aussi d'autres valeurs intéressantes comme le Seed par exemple:
Nous avons à notre disposition pas moins de 3 fonctions utiles :
-
IDENT_CURRENT() : Récupère la dernière valeur générée d'une colonne identité.
-
IDENT_SEED() : Récupère la valeur de départ d'une colonne identité.
-
IDENT_INCR() : Récupère l'incrément d'une colonne identité
Ce qui donne, par code un truc du genre :
Declare @tableName varchar(20) = 'dbo.DatabaseLog'
SELECT @tableName as [Table],
IDENT_SEED(@tableName) AS Seed,
IDENT_INCR(@tableName) AS Increment,
IDENT_CURRENT(@tableName) AS Current_Identity
Et là biensûr pas de problème particulier pour récupérer ces valeurs depuis du code .Net !
Ah là là, les vacances sont finies... 

Je viens de m'arracher la tête sur un vil bug impliquant WCF et WPF via l'ObjectDataProvider
Au bout de 10 appels de mon service (via le proxy généré avec un Add Service Reference) j'atteins le MaxConcurrentSessions, fixé de base à 10.
Le code serveur n'ayant rien d'extraordinaire, je passe directement à mon code client, dans mon formulaire WCF
ObjectDataProvider odpServiceType;
private void Window_Loaded(object sender, RoutedEventArgs e)
{
//Set source for service type
odpServiceType = new ObjectDataProvider();
// Make it Asynchronous
odpServiceType.IsAsynchronous = true;
odpServiceType.ObjectType = typeof(MyServiceProxy.MyServiceClient);
odpServiceType.MethodName = "GetServiceTypes";
// Set DataContext
this.comboBox1.DataContext = odpServiceType;
}
J'utilise mon ObjectDataProvider en lui précisant le type d'objet et la méthode à appeller.
Je lance l'application 10 fois, la 11eme se vautre lamentablement.
Hop un coup de Service Trace Viewer me donne vite l'indication que je cherche :
MaxConcurrentSessions atteint !!!
Et oui, l'objectdataprovider n'appelle pas explicitement le close de mon channel !
Résolution facile, enfin une fois qu'on a compris :)
Sur le Close de ma Window, nous castons l'instance crée par l'objectdataprovider en MyServiceClient, et nous appellons explicitement la méthode close:
protected override void OnClosing(System.ComponentModel.CancelEventArgs e)
{
MyServiceProxy.MyServiceClient service = odpServiceType.ObjectInstance
as MyServiceProxy.MyServiceClient;
if (service != null && service.State != CommunicationState.Closed)
service.Close();
base.OnClosing(e);
}
Bon WCF-WPF à tous 
Tiens, en passant, le nouveau logo de SQL Server 2008.
J'aime bien 
Source : http://blogs.msdn.com/wesleyb/archive/2008/06/03/sql-server-logo.aspx
Et voilà, le MSDN Tour est de passage à Marseille, et BEWISE est présent !
Les Sessions ont bien commencé, certaines salles sont déjà bien pleine, c'est bon signe :)
J'ai quelques photos, prises ce matin par Laurent Galmiche, responsable de l'agence BEWISE à Aix en Provence :
Photo 1 : Le calme de l'accueil avant la tempête
Photo 2 : La tempête débarque 
Photo 3 : Le stand BEWISE, où nous nous retrouvons entre les sessions (notez la touch-classe from Vertice)
Photo 4 : Préparation d'une session
Photo 5 : Un session DEV en cours

Avec l'arrivée du Framework 3.5 SP1 béta, de nouvelles classes ont fait leur apparition.
Notamment un ensemble de classes pour gérer le nouveau type SQL SERVER 2008 : FILESTREAM.
Lors de mes différentes présentations sur le sujet, j'ai toujours du utiliser une classe encapsulant un appel à une dll C, que je ne présentais pas d'ailleurs :) en expliquant que "bientôt" nous aurions droit à de vrais classes managed pour gérer tout ça
Et bien, c'est le cas; le framework (3.5 SP1 béta) est là !
Maintenant, tout devient (relativement) simple 
D'abord le script de création d'une table contenant un type FILESTREAM :
-- 1. Enable FILESTREAM support
EXEC [sp_filestream_configure] @enable_level = 3;
-- 2. Create a database with a File Group that contains FILESTREAM
CREATE DATABASE FileManagement
ON
PRIMARY (
NAME = FileManagement_Primary,
FILENAME = 'c:\temp\data\FileManagement.mdf'),
FILEGROUP FileStreamGroup CONTAINS FILESTREAM (
NAME = FileManagement_FileGroup,
FILENAME = 'c:\temp\data\FileManagement')
LOG ON ( NAME = FileManagement_Log,
FILENAME = 'c:\temp\data\FileManagementLog.ldf')
GO
-- 3. Create a Table with FILESTREAM
CREATE TABLE [dbo].[Files]
(
FileID uniqueidentifier NOT NULL ROWGUIDCOL PRIMARY KEY,
FileContents varbinary(max) FILESTREAM DEFAULT(0x)
)
GO
En préambule, on crée une transaction (BIENSUR !)
SqlTransaction tx = conn.BeginTransaction();
J'insère dans ma table, contenant un filestream, une ligne (tout ça pour récupérer un contexte de transaction par la suite)
SqlCommand insertFileCommand = conn.CreateCommand();
insertFileCommand.Transaction = tx;
insertFileCommand.CommandText = "INSERT INTO Files (FileID) VALUES (@FileID)";
Guid newFileID = Guid.NewGuid();
insertFileCommand.Parameters.Add("@FileID", SqlDbType.UniqueIdentifier).Value = newFileID;
insertFileCommand.ExecuteNonQuery();
Je récupère le contexte de transaction :
SqlCommand getPathAndTokenCommand = conn.CreateCommand();
getPathAndTokenCommand.Transaction = tx;
getPathAndTokenCommand.CommandText = "SELECT FileContents.PathName(), GET_FILESTREAM_TRANSACTION_CONTEXT() FROM Files WHERE FileID = @FileID";
getPathAndTokenCommand.Parameters.Add("@FileID", SqlDbType.UniqueIdentifier).Value = newFileID;
SqlDataReader tokenReader = getPathAndTokenCommand.ExecuteReader(CommandBehavior.SingleRow);
tokenReader.Read();
SqlString filePathName = tokenReader.GetSqlString(0);
SqlBinary fileToken = tokenReader.GetSqlBinary(1);
tokenReader.Close();
Et maintenant j'utilise ce fameux nouveau type, comme un simple type FileStream (j'ouvre un flux, et j'écris dedans !)
FileStream inputFile = File.OpenRead("TextFile1.txt");
SqlFileStream sqlFile = new SqlFileStream(filePathName.Value, fileToken.Value, System.IO.FileAccess.Write);
byte[] buffer = new byte[512 * 1024]; // 512Kb
int bytesRead = inputFile.Read(buffer, 0, buffer.Length);
while (bytesRead > 0)
{
sqlFile.Write(buffer, 0, bytesRead);
bytesRead = inputFile.Read(buffer, 0, buffer.Length);
}
J'oublie pas de tout fermer hein ;)
sqlFile.Close();
inputFile.Close();
tx.Commit();
conn.Close();
Et voilà !
Bon FILESTREAM ! 
Un article très bien écrit par mon collègue Djeepy sur la Géolocalisation dans SQL SERVER 2008
Premiers pas dans l’espace
Pour vous mettre en appétit :


Bonne lecture !
Je viens d'installer le SP1 du Framework 3.5 ainsi que le SP1 de Visual Studio 2008.
Il est clair qu'il y a beaucoup de nouveautés trés excitantes dans le SP1.
Support de l'intellisense poussé de Javascript, Support d'Entity Framework, Astoria, AJAX History, amélioration des perfs de Visual Studio 2008 etc ...
Mais aussi plus proche de SQL Server 2008, le support de celui dans Visual Studio 2008 (ENFIN !!)
Et bien sachez que je viens de découvrir une nouveauté peu relayée du SP1.
Une mise à jour du Designer de Sync Services qui supporte non seulement SQL Server 2008, mais aussi une des features de celui ci : Le Change Tracking !
Notez le petite case à cocher : "User Sql Server Change Tracking"
J'avais déjà auparavant fais du change tracking avec SQL Server 2008 et Sync Services (cf ma démo au Tech Days 2008) mais l'avoir intégré nativement dans le designer, je trouve ça juste ... cool !
Bon là il est un peu tard, mais promis je vais fous faire un petit article sur le Change Tracking et Sync Services, qui sont "ON NE PEUT PLUS" complémentaire l'un et l'autre !
Restez à l'écoute, je me sens d'humeur inspirée !!!
Bonjour à tous,
| Je viens de découvrir un tool absolument "Must Have" pour tout bon développeur qui se respecte : LinqPad Cet utilitaire est grosso-modo un Notepad Pour Linq. |
J'adore !
Vous lancez et vous faites du LINQ :
J'ai trouvé tout de suite, un cas d'utilisation direct de cet outil.
Je veux faire du Linq To Sql dans une base de donnée, vite fait pour voir le contenu de la table Client.
Et bien avec LinqPad, pas besoin de créer un projet VS.Net, de créer un DataContext, une classe console, ou une winforms, blah blah blah ...
Je lance juste LinqPad, je me connecte à ma base de donnée (si ça n'a pas été déjà fait dans une session antérieure) et j'interroge directement ma table client... en LINQ !
En plus vous trouverez plein d'exemples, que ce soit LINQ simple ou LINQ to SQL ou encore LINQ To XML.
Enormissime !
Au menu de ce nouvel opus, la synchronisation multi-tiers :)
Le principe ici étant d'exposer, non pas son serveur SQL SERVER 2005, mais plutôt un service WCF, mettant à disposition les données à synchroniser.
Je vous rappelle au passage aussi les deux premiers articles de cette série
Bonne synchro à tous !
Edit : Tiens je viens de trouver un super en article en français de Redo sur Sync Framework. Une bonne lecture de plus pour se familiariser sur cette techno. Hop c'est par ici : Sync Framework par Redo sur asp-php.net
Il existe un "bug d'installation" lors d'une tentative d'installation de SQL Server 2008, suivi d'une installation de SQL Server 2005 sur un Windows Server 2008.
L'installation de SQL Server 2005 échoue dans quelques cas.
Voici les patchs correctifs. A installer aprés l'installation de SQL Server 2008, mais avant SQL Server 2005 :
Bon je vous l'accorde ce cas de configuration est assez rare, mais j'étais en plein dedans :)
Juste une petite astuce lorsque vous voulez vérifier si votre Serveur SQL SERVER 2005 est bien à jour, au niveau service pack :)
Pour vérifier la version installée, exécuter le script suivant :
SELECT SERVERPROPERTY('productversion') as 'Version SQL SERVER', SERVERPROPERTY ('productlevel') as 'Service Pack appliqué', SERVERPROPERTY ('edition') as 'Edition'
Résultat attendu :
Note : le numéro de version (colonne 1) peut varier suivant les HotFix appliqué sur l’Instance SQL SERVER 2005. La donnée essentielle étant la deuxième colonne « Service Pack appliqué »
Pour information, les versions des bases de données SQL sont (sans prendre en compte les hotfixs)
| SQL SERVER | VERSION |
| SQL 2005 | 9.00.1399.06 |
| SQL 2005 SP1 | 9.00.2047.00 |
| SQL 2005 SP2 | 9.00.3043.00 |
| SQL 2008 CTP3 | 10.0.1019.17 |
| SQL 2008 CTP4 | 10.0.1049.14 |
| SQL 2008 CTP5 | 10.0.1075.23 |
| SQL 2008 CTP6 | 10.0.1300.13 |
Informations reprises du blog de Patrick Guimonet
Vous aurez donc noté que chez moi, la version 9.0.3054 diffère de la version SP2 "classique" 9.0.3043, car j'ai appliqué des hot fixes.
Bon Select à tous !
Il se peut que vous ayez installé sur votre serveur de développement, comme moi, plusieurs instances de SQL SERVER.
Du coup, vous vous retrouvez avec plusieurs instances nommées.
Dans mon cas par exemple j'ai cette architecture :
- Sql Server 2005 : (local)\sql2005
- Sql Server Express : (local)\sqlexpress
- Sql Server 20008 CTP6 : (local)\sql2008
Vous noterez que je n'ai pas d'instance par défaut.
J'ai eu un problème récessemnt lorsque j'ai essayé d'accès à SSIS via la console Management.
En effet, lors de la tentative de connexion à mon serveur SSIS, j'ai eu une vieille erreur pas belle qui me dit que je n'ai pas le droit d'ouvrir mon package SSIS parce que le serveur n'est pas accessible.. bla .. bla ... bla
Tout ça parce qu'un fichier de mapping a la bonne idée d'indiquer que mon instance 2005 est l'instance par défaut (rhooo).
Le fichier au doux nom de MsDtsSrvr.ini.xml est placé ici chez moi :
Il suffit de l'ouvrir et de remplacer (voir compléter) la ligne de mapping :
Et voilà !
Attention : Pensez à redémarrer votre service SSIS !
Happy Connexion !
Comment SQL SERVER inteprète t'il ce genre de syntaxe : 14/02/99 ?
Biensur on va dire le 14 février 1999
Mais comment interprète t'on ceci :14/02/02
Biensur on va dire le 14 février 2002
Oui mais pourquoi SQL SERVER a t'il interprété la première date en 1900 et quelque et la deuxième en 2000 et quelques ?
Eh bien tout simplement, SQL SERVER est paramétré pour utiliser ce qu'on appelle une date de coupure. la date de coupure étant 49.
Aprés 49, SQL SERVER interprète les dates en 1950 et plus.
Avant 49, SQL SERVER interprète 2049 et moins.
Ces deux digits sont biensur paramétrable dans SQL SERVER. Propriétés du serveur, onglet Avancé :
options advanced d'un serveur 2005
Et, comme 99 % des choses accessibles via la console management, vous pouvez faire la même chose en T SQL :
EXEC sys.sp_configure N'show advanced options', N'1' RECONFIGURE WITH OVERRIDE
GO
EXEC sys.sp_configure N'two digit year cutoff', N'2049'
GO
RECONFIGURE WITH OVERRIDE
GO
EXEC sys.sp_configure N'show advanced options', N'0' RECONFIGURE WITH OVERRIDE
GO
Et voilà, un paramètre éclairci :)
Plus de Messages
Page suivante »