Conseils et formations : vos deux atouts pour réussir !
Accueil > Développement > Articles
SQLServer 2008 Insert multiple et merge

Insertion de lignes multiples :


L'objectif est de créer plusieurs lignes dans la base sur un seul ordre INSERT .

Tout d'abord, rappelons les INSERT classiques ....

Soit une simple table :

    create table [dbo].[Matable](

    [MaCle] [int] NOT null,

    [Valeur] [varchar](50) null

    ) ON [primary]



On insère une ligne avec les colonnes dans l'ordre supposé du dictionnaire :


    insert into dbo.Matable

    values

    (1,'Dominique')



C'est déconseillé car , que se passe-t-il si vous changez la structure de la table ??

Exemple amusant :


    drop table [dbo].[Matable]

    go

 

    create table [dbo].[Matable](

    [MaCle] [int] NOT null,

    [UneAutreValeur] [varchar](50) null

    [Valeur] [varchar](50) null

    ) ON [primary]

 


puis :


    insert into dbo.Matable

    values

    (1,'Dominique')

 


Bien sûr, la colonne cible n'est plus celle que l'on pense !

Il faut utiliser :

    insert into dbo.Matable (MaCle,Valeur)

    values

    (2,'David')



Et maintenant, la nouveauté SQL2008 :

    insert into dbo.Matable (MaCle,Valeur)

    values

    (3,'David'),(4,'Maelle')

 


On insère dans un seul ordre DML n lignes.


cela peut être sympathique pour des scripts de chargement de données de réference....

L'instruction MERGE :


Vous avez sans doute tous eu, comme moi, à résoudre le problème suivant :

j'ai des données dans une table de référence, mais la source de mise à jour de ces données est multiple,je vais donc avoir à fusionner (MERGE) deux tables pour en obtenir une seul à jour.

Ceci est très fréquent avec des progiciels dont la propagation des mises à jour n'est pas temps réel.

Voyons la syntaxe de cette fusion :

MERGE [ into ] tableCible [ [ AS ] AliasDetable ]

[ WITH USING tableSource

ON ConditionDeRecherche

[ WHEN MATCHED THEN InstructionsSiCorrespondance ]

[ WHEN NOT MATCHED THEN InstructionsSiNonCorrespondance ]

 

 

Et maintenant des données de test pour voir le tout en fonctionnement :

    create table Source

    (NoPersonnel int not null,

    Nom varchar(50),

    constraint pk_Source primary key clustered (NoPersonnel))

 

    insert into Source values (1,'Pierre'),(2,'Paula épouse Durand')

 

 

    select * from Source



NoPersonnel Nom
----------- --------------------------------------------------
1 Pierre
2 Paula épouse Durand

(2 row(s) affected)


    create table Cible

    (NoPersonnel int not null,

    Nom varchar(50),

    constraint pk_Cible primary key clustered (NoPersonnel))

 

    insert into Cible values (2,'Paula')

 

 

    select * from Cible

 

NoPersonnel Nom
----------- --------------------------------------------------
2 Paula

(1 row(s) affected)


L'objectif étant bien sûr, que notre 'épouse Durand' écrase la donée cible, et que la ligne manquante soit insérée.

Ecrivons donc l'ordre MERGE :


    MERGE into Cible

    using [Source]

    ON Cible.NoPersonnel = Source.NoPersonnel

    WHEN MATCHED THEN

    update set Nom = Source.nom

    WHEN NOT MATCHED THEN

    insert (NoPersonnel,Nom) values (Source.NoPersonnel,Source.Nom);

 

 

    select * from Cible



NoPersonnel Nom
----------- --------------------------------------------------
1 Pierre
2 Paula épouse Durand

(2 row(s) affected)

On se retrouve bien avec les données à niveau après fusion.

Attention, comme très souvent dans les nouvelles évolutions de TSQL, le ; est obligatoire en fin d'instruction :

    MERGE into Cible

    using [Source]

    ON Cible.NoPersonnel = Source.NoPersonnel

    WHEN MATCHED THEN

    update set Nom = Source.nom

    WHEN NOT MATCHED THEN

    insert (NoPersonnel,Nom) values (Source.NoPersonnel,Source.Nom)



Msg 10713, Level 15, State 1, Line 7
A MERGE statement must be terminated by a semi-colon (;).

Ayant eu à écrire moi-même un interpréteur de langage il y a quelques années, je pense que la raison d'être de ce ; est lié au caractère non déterministe de certaines formulations :
Un langage informatique DOIT être déterministe, c'est à dire qu'il ne peut y avoir qu'une interprétation possible d'une phrase donnée (ce qui n'est pas le cas de notre bon vieux Français, et encore moins de l'Anglais, Par ex : le météorologue voyait venir la dépression...)

Conclusion :


Voilà un MERGE que l'on attendait depuis longtemps et qui devrait économiser bien des efforts aux développeurs (en tout cas à ceux qui veulent encore se servir des bases de données)...

 ‭(Masqué)‬ WebPart1 Web Part

/Developpement/SQLServer 2008 Insert multiple et merge/