UPDATE conditionnel T-SQL (v2)
J'ai une table:
Message (MessageID int, Subject nvarchar(100), Body nvarchar(max))
Après qu'un message est en cours de mise à jour sur l'INTERFACE utilisateur, j'appelle une procédure stockée pour mettre à jour la table. Dans certains cas, l'utilisateur peut mettre à jour juste l'objet, dans d'autres cas, juste le corps. Je veux que cette procédure stockée uniquement mettre à jour ce qui a changé, je suis donc aussi en passant des drapeaux indiquant si l'objet ou le corps a été mis à jour à:
create proc UpdateMessage(
@MessageID int,
@Subject nvarchar(100),
@Body nvarchar(max),
@SubjectChanged bit,
@BodyChanged bit)
Et maintenant, je suis confus comment construire le conditionnel UPDATE
déclaration. Ma première pensée a été d'utiliser CASE
:
Update [Message]
SET
CASE WHEN @SubjectChanged = 1 THEN [Subject] = @Subject ELSE 1=1 END,
CASE WHEN @BodyChanged = 1 THEN Body = @Body ELSE 1=1 END,
WHERE MessageID = @MessageID
... mais qui ne semble pas être une syntaxe correcte comme CASE
doit être le côté droit d'une affectation.
Aucune idées de comment je pourrais faire? (Et garder à l'esprit que dans la réalité il y a 6 paramètres qui peuvent être mis à jour, pas deux)
source d'informationauteur Andrey | 2009-10-10
Vous devez vous connecter pour publier un commentaire.
La syntaxe requise pour la création de votre déclaration est:
si vous voulez continuer à tenir à bout de toutes les suggestions.
N. b. si vous laissez l'AUTRE personne [Sujet] le cadre de l'AFFAIRE états, plutôt que d'ignorer la mise à JOUR, il définit le champ NULL.
Qui devrait vraiment être tout ce dont vous avez besoin. Toutefois, si vous peut vraiment pas mettre à jour le champ si elle n'a pas changéalors vous aurez à faire dans des déclarations séparées.
Votre meilleur pari, de loin, est d'utiliser explicitement SI les déclarations:
À partir d'un point de vue des performances, rien de mieux que cela. Parce que SQL peut voir lors de la compilation de la requête que vous ne mettez à jour le Corps, ou le Sujet, ou les deux, il peut générer le plan approprié, par exemple de ne pas prendre la peine d'ouvrir (pour mise à jour) à l'index non cluster que vous avez sur le Sujet (si vous en avez un, bien sûr) quand vous ne mettez à jour Corps.
À partir d'un code de point de vue qualité, c'est une catastrophe, un cauchemar à maintenir. Mais en reconnaissant le problème, c'est 80% de résoudre le problème 🙂 . Vous pouvez utiliser des techniques de génération de code, par exemple pour maintenir un tel problème procédures.
Une autre approche possible est en fait d'utiliser le SQL dynamique, construire la mise à JOUR de la procédure et l'utilisation sp_executesql. Il a son propre ensemble de problèmes, comme tout le SQL dynamique. Il y a des ressources sur le SQL dynamique des problèmes, et il y a des solutions de rechange et des solutions, voir La Malédiction et la bénédiction de SQL Dynamique.
Me semble que vous perdez beaucoup d'efforts. Si vous récupérez les six valeurs, les afficher à l'utilisateur (interface utilisateur) et ils peuvent changer d'une variable nombre d'entre eux
et appuyer sur un bouton "enregistrer" - puis il suffit de mettre à jour tous les 6 champs chaque fois, obtenir les nouvelles valeurs dans les champs de saisie de l'utilisateur.
Certains peuvent ne pas avoir changé, mais tant pis. Un code bien plus simple de cette façon.
Utiliser les valeurs par DÉFAUT pour les paramètres de procédure stockée.
Ensuite, vous pouvez structurer votre mise à jour de cette façon:
Je ne suis pas sûr si c'est la meilleure façon de le faire, mais peut-être que vous pouvez essayer
Je vous recommande fortement d'utiliser Adam Robinson méthode si vous avez besoin de cela pour être dans une seule procédure stockée.
Même mieux serait de tout simplement utiliser des procédures stockées pour chacune de ces mises à jour.