Mim

Select * from Seb where Sujets in (SQL Server 2008, ADO.NET, Visual Studio 2008)
Sync Services : Client Sql Server Express

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 Smile

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)
    • Récupère les changements survenus sur la source de données client.
  • public override SyncAnchor GetTableReceivedAnchor(string tableName)
    • Récupère la dernière ancre générée de la table paramètre 
      (pour rappel l'ancre étant une données unique identifiant dans
      le temps, le dernier changement survenu sur une table)
  • 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)
    • Ecrit un ancre de dernière modification dans la source de données, 
      pour une table donnée
  • public override void SetTableSentAnchor(string tableName, 
    SyncAnchor anchor)
    • Ecrit un ancre de dernier envoi dans la source de données, 
      pour une table donnée

 

N'hésiter pas à récupérer ce petit exemple d'implémentation qui s'avère, au final, plutôt simple !

Max(), Dbcc CheckIdent(), Ident_Current()

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 :

  1. IDENT_CURRENT() : Récupère la dernière valeur générée d'une colonne identité.

  2. IDENT_SEED() : Récupère la valeur de départ d'une colonne identité.

  3. 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
 
Ident_current 
 

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... Big GrinParty

 
WCF WPF ObjectDataProvider MaxConcurrentSessions

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 :

 

image

 

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 Winking

Ils l'ont fait !

http://www.microsoft.com/france/sql/ilslontfait/

SQL SERVER 2008 nouveau logo

Tiens, en passant, le nouveau logo de SQL Server 2008.

J'aime bien Applause

 logo-header-sql08-dg

Source : http://blogs.msdn.com/wesleyb/archive/2008/06/03/sql-server-logo.aspx

Aujourd'hui MSDN Tour à Marseille !
MTT08 Mtt_Bewise  

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

CIMG1324

Photo 2 : La tempête débarque Smile

CIMG1331

Photo 3 : Le stand BEWISE, où nous nous retrouvons entre les sessions (notez la touch-classe from Vertice)

CIMG1327

Photo 4 : Préparation d'une session

CIMG1325

Photo 5 : Un session DEV en cours

CIMG1334

SqlFileStream

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 Happy

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 ! Applause

Premiers pas dans l’espace

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 :

image_3

image_thumb_5

Bonne lecture ! 

Fx 3.5 sp1 beta et Sync Services for ADO.Net

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 !

LocalDatabaseCacheDesigner01

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 !!!

LinqPad

Bonjour à tous,

linqpadlogo

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 :

image

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 !

Chapitre III : Sync. Services for ADO.NET et WCF
Je viens de publier un nouvel article sur le site TechHeadBrothers, suite de mes péripéties avec Sync. Services for ADO.NET

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

Installation SQL Server 2008 et Windows Server 2008

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 :)

SQL SERVER : Les versions et services pack

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 :

SQL_versions

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 !

SQL SERVER et SSIS. Instance nommée

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 :

  1. Sql Server 2005 : (local)\sql2005
  2. Sql Server Express : (local)\sqlexpress
  3. 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 : MsDtsSrvr

Il suffit de l'ouvrir et de remplacer (voir compléter) la ligne de mapping :

SSIS_Xml_Config

Et voilà !

Attention : Pensez à redémarrer votre service SSIS !

RestartSSIS

Happy Connexion !

Astuce : two digit year cutoff

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é :

twoyearcutoff
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 »