Avant d'écrire une déclaration de mise à jour, devrais-je vérifier s'il existe?
Quelqu'un m'a dit de faire ça
Il évite donc d'écrire inutilement au journal des transactions pour une valeur qui existe déjà,
Et prend uniquement un verrou partagé permettant d'autres lectures par rapport à un verrou exclusif.
[.____] Ils ont dit imaginer une transaction fonctionnant comme ce plusieurs temps pour différentes valeurs, vous recevriez des verrous exclusifs tout le temps plutôt que des serrures partagées.
Collaborateur mentionné, en regardant Tableau de compatibilité de verrouillage , il ne peut y avoir deux serrures de mise à jour lors de la recherche, mais il peut y avoir deux serrures partagées. Ainsi, lorsque vous "recherchez des lignes à mettre à jour" lorsque ce ne sont pas de valeurs à mettre à jour, une fausse verrouillage de la mise à jour peut bloquer une véritable mise à jour. Quelqu'un peut-il invalider cette réclamation?
if not exists
(
select FavoriteColor
from dbo.Person
where Name = 'Bob'
and FavoriteColor = 'Green'
)
update dbo.Person
set FavoriteColor = 'Green'
where Name = 'Bob'
Même question, à l'exception de la suppression maintenant, devrais-je vérifier s'il existe?
if exists
(
select FavoriteColor
from dbo.Person
where Name = 'Bob'
and FavoriteColor = 'Green'
)
delete dbo.Person
where Name = 'Bob' and FavoriteColor = 'Green'
Nous utilisons SQL Server 2016.
Généralement, ce modèle est plus efficace et beaucoup moins susceptible de conduire à des blocages ou à d'autres problèmes de concurrence:
UPDATE dbo.Person
SET FavoriteColor = 'Green'
WHERE Name = 'Bob'
AND COALESCE(FavoriteColor, '') <> 'Green';
DELETE dbo.Person
WHERE Name = 'Bob'
AND FavoriteColor = 'Green';
... Tout simplement parce que vous devez seulement vérifier la ligne une fois. Vous pouvez également écrire le UPDATE
comme:
UPDATE dbo.Person
SET FavoriteColor = 'Green'
WHERE Name = 'Bob'
AND (FavoriteColor IS NULL OR FavoriteColor <> 'Green');
... qui peut être plus adapté à l'index dans certains cas.
Les verrous exclusifs pour les opérations d'écriture ne sont pas prises avant juste avant la modification d'une ligne à modifier. Tandis que SQL Server est recherche pour les lignes à mettre à jour, il utilise des serrures de mise à jour, qui ne sont pas en conflit avec des lectures simultanées. Le verrou de mise à jour est libéré immédiatement si SQL Server détermine que la ligne en cours de vérification ne se qualifie pas pour la mise à jour.
La seule raison pour laquelle je peux penser à l'utilisation de l'if exists
méthode est s'il y a UPDATE/DELETE
déclenche dans la table que vous souhaitez éviter d'être tirés, surtout si vous avez INSTEAD OF
déclencheurs qui peuvent prendre des mesures avant que toute mise à jour ou toute suppression soit réellement tentée.
Il est normalement préférable d'écrire DML de sorte que seules les lignes nécessitant un changement sont affectées.