[SQL Serveur] Update avec une jointure externe
Voilà la demande: j’ai une table “véhicule” qui contient des immatriculations mais certains de ces véhicules ont changés d’immatriculation. Donc j’ai une autre table « modifImmat »qui contient un champ “ancienne immatriculation” et un champ “nouvelle immatriculation”.L’idée est de mettre à jour la table véhicule avec les nouvelles immatriculations.
Donc voici les scripts de création des 2 tables :
CREATE TABLE dbo.ModifImmat
(
AncienneImmat varchar(50) NULL,
NouvelleImmat varchar(50) NULL
) ON [PRIMARY]
GO
CREATE TABLE dbo.Vehicules
(
idVehicule int NOT NULL IDENTITY (1, 1),
Immat varchar(50) NULL
) ON [PRIMARY]
GO
ALTER TABLE dbo.Vehicules ADD CONSTRAINT
PK_Vehicules PRIMARY KEY CLUSTERED
(
idVehicule
) WITH( STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF,
ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO
Ensuite on remplit les tables (ici j’utilise une fonctionnalite sql2008 qui permet de ne pas répéter les insert…values…):
--On remplit la table Vehicule
INSERT INTO [toto].[dbo].[Vehicules]
([Immat])
VALUES
('123 ab 31'),('234 bc 31'),('345 ab 31'),('456 bc 31')
GO
--On remplit la table ModifImmat
INSERT INTO [toto].[dbo].[ModifImmat]
([AncienneImmat]
,[NouvelleImmat])
VALUES
('123 ab 31','AB 123 31'),
('234 bc 31','BC 234 31'),
('345 ab 31','AB 345 31')
GO
Ok donc voila ce que ça donne :
On voit ici que le véhicule « 456 bc 31 » n’a pas de nouvelle immatriculation alors que les autre oui donc on va essayer la première version de notre update :
L’astuce lorsque on teste une requête est de l’encadre d’un begin transaction….. rollback transaction pour que la ou les requêtes soient jouées et annulées juste derrière donc à nous de mettre les select qui vont bien pour voir si notre requête est ok ou pas.
Ici ce n’est pas !! En fait on voit que le véhicule qui n’a pas d’immatriculation vient de perdre grâce à notre requête son immatriculation : pas cool.
Donc on va spécifier au update que si le select ne renvoi rien (il n’y a pas d’occurrence de l’immatriculation du véhicule dans la table modif immat), il doit écrire l’immatriculation présente dans la table véhicule. Voici ce que donne la version deux :
Je pense que c’est ce qui était demandé.
Attardons nous sur le update :
update dbo.Vehicules
set Immat=isnull((select NouvelleImmat
from dbo.ModifImmat where AncienneImmat=Immat),Immat)
Ici on voit que je teste le retour du select, si il est null je met l’immatriculation de la table véhicule, sinon je met la nouvelle immatriculation de la table modifimmat.
L’autre astuce est de lier dans le where du select un champ qui correspond à la table du select avec un autre champ qui lui n’est pas dans le select mais à l’extérieur des parenthèses.