J'ai besoin d'écrire un déclencheur d'insertion, de mise à jour sur la table A qui supprimera toutes les lignes de la table B dont une colonne (par exemple Desc) a des valeurs comme la valeur insérée / mise à jour dans la colonne de la table A (par exemple Col1). Comment pourrais-je l'écrire pour pouvoir gérer à la fois les cas de mise à jour et d'insertion. Comment déterminer si le déclencheur est exécuté pour une mise à jour ou une insertion.
la source
la source
Beaucoup de ces suggestions ne sont pas prises en compte si vous exécutez une instruction de suppression qui ne supprime rien.
Supposons que vous essayez de supprimer où un ID équivaut à une valeur qui n'existe pas dans la table.
Votre déclencheur est toujours appelé mais il n'y a rien dans les tables supprimées ou insérées.
Utilisez ceci pour être sûr:
Un merci spécial à @KenDog et @Net_Prog pour leurs réponses.
J'ai construit cela à partir de leurs scripts.
la source
J'utilise ce qui suit, il détecte également correctement les instructions de suppression qui ne suppriment rien:
la source
Après de nombreuses recherches, je n'ai pas pu trouver d'exemple exact d'un seul déclencheur SQL Server qui gère les (3) trois conditions des actions de déclenchement INSERT, UPDATE et DELETE. J'ai finalement trouvé une ligne de texte qui parlait du fait que lorsqu'un DELETE ou UPDATE se produit, la table DELETE commune contiendra un enregistrement pour ces deux actions. Sur la base de ces informations, j'ai ensuite créé une petite routine d'action qui détermine pourquoi le déclencheur a été activé. Ce type d'interface est parfois nécessaire lorsqu'il y a à la fois une configuration commune et une action spécifique à se produire sur un déclencheur INSERT vs UPDATE. Dans ces cas, créer un déclencheur distinct pour la mise à jour et l'INSERT deviendrait un problème de maintenance. (c.-à-d. les deux déclencheurs ont-ils été mis à jour correctement pour la correction d'algorithme de données commune nécessaire?)
À cette fin, je voudrais donner l'extrait de code d'événement multi-déclencheur suivant pour gérer INSERT, UPDATE, DELETE dans un déclencheur pour un serveur Microsoft SQL Server.
la source
Je crois que les si imbriqués sont un peu déroutants et:
;)
la source
la source
Essaye ça..
la source
bien que j'aime aussi la réponse publiée par @Alex, j'offre cette variante à la solution de @ Graham ci-dessus
cela utilise exclusivement l'existence d'enregistrement dans les tables INSERTED et UPDATED, par opposition à l'utilisation de COLUMNS_UPDATED pour le premier test. Il apporte également un soulagement au programmeur paranoïaque sachant que le cas final a été considéré ...
vous obtiendrez NOOP avec une déclaration comme celle-ci:
la source
END
soit mal indenté! (provoquant la question de savoir où le premierBEGIN
est fermé)Cela pourrait être un moyen plus rapide:
la source
Un problème potentiel avec les deux solutions proposées est que, selon la façon dont elles sont écrites, une requête de mise à jour peut mettre à jour zéro enregistrement et une requête d'insertion peut insérer zéro enregistrement. Dans ces cas, les jeux d'enregistrements insérés et supprimés seront vides. Dans de nombreux cas, si les jeux d'enregistrements insérés et supprimés sont vides, vous souhaiterez peut-être simplement quitter le déclencheur sans rien faire.
la source
J'ai trouvé une petite erreur dans la solution Grahams autrement cool:
Ce devrait être IF COLUMNS_UPDATED () < > 0 - insérer ou mettre
à jour au lieu de> 0 probablement parce que le bit supérieur est interprété comme le bit de signe entier SIGNÉ ... (?). Donc au total:
la source
Cela fait l'affaire pour moi:
Puisque toutes les colonnes ne peuvent pas être mises à jour à la fois, vous pouvez vérifier si une colonne particulière est mise à jour par quelque chose comme ceci:
la source
la source
J'aime les solutions «élégantes en informatique». Ma solution ici frappe les pseudotables [inséré] et [supprimé] une fois chacun pour obtenir leurs statuts et place le résultat dans une variable mappée. Ensuite, chaque combinaison possible de INSERT, UPDATE et DELETE peut facilement être testée tout au long du déclencheur avec des évaluations binaires efficaces (sauf pour la combinaison improbable INSERT ou DELETE).
Il suppose que peu importe ce qu'était l'instruction DML si aucune ligne n'était modifiée (ce qui devrait satisfaire la grande majorité des cas). Ainsi, même si elle n'est pas aussi complète que la solution de Roman Pekar, elle est plus efficace.
Avec cette approche, nous avons la possibilité d'un déclencheur "FOR INSERT, UPDATE, DELETE" par table, ce qui nous donne A) un contrôle complet sur l'ordre des actions et b) une implémentation de code par action multi-action applicable. (Évidemment, chaque modèle de mise en œuvre a ses avantages et ses inconvénients; vous devrez évaluer vos systèmes individuellement pour déterminer ce qui fonctionne vraiment le mieux.)
Notez que les instructions «existe (sélectionnez * à partir de« inséré / supprimé »)» sont très efficaces car il n'y a pas d'accès disque ( https://social.msdn.microsoft.com/Forums/en-US/01744422-23fe-42f6 -9ab0-a255cdf2904a ).
la source
Solution rapide MySQL
Au fait: j'utilise MySQL PDO.
(1) Dans une table d'incrémentation automatique, obtenez simplement la valeur la plus élevée (nom de ma colonne = id) de la colonne incrémentée une fois que chaque script est exécuté en premier:
(2) Exécutez la requête MySQL comme vous le feriez normalement, et transtypez le résultat en entier, par exemple:
(3) Après la requête "INSERT INTO ... ON DUPLICATE KEY UPDATE", obtenez le dernier identifiant inséré de la manière que vous préférez, par exemple:
(4) Comparez et réagissez: Si le lastInsertId est supérieur au plus élevé du tableau, c'est probablement un INSERT, non? Et vice versa.
Je sais que c'est rapide et peut-être sale. Et c'est un vieux post. Mais, hé, je cherchais une solution depuis longtemps, et peut-être que quelqu'un trouve mon chemin quelque peu utile de toute façon. Bonne chance!
la source
façon simple
la source
Dans le premier scénario, j'ai supposé que votre table avait une colonne IDENTITY
Dans le deuxième scénario, vous n'avez pas besoin d'utiliser la colonne IDENTITTY
la source
SI sa mise à jour
si son insertion
la source
J'utilise ces
exists (select * from inserted/deleted)
requêtes depuis longtemps, mais ce n'est toujours pas suffisant pour les opérations CRUD vides (lorsqu'il n'y a pas d'enregistrementsinserted
et dedeleted
tables). Donc, après avoir étudié un peu ce sujet, j'ai trouvé une solution plus précise:Il est également possible d'utiliser
columns_updated() & power(2, column_id - 1) > 0
pour voir si la colonne est mise à jour, mais ce n'est pas sûr pour les tables avec un grand nombre de colonnes. J'ai utilisé une méthode de calcul un peu complexe (voir l'article utile ci-dessous).En outre, cette approche classifiera toujours de manière incorrecte certaines mises à jour comme des insertions (si chaque colonne de la table est affectée par la mise à jour), et elle classera probablement les insertions où seules les valeurs par défaut sont insérées en tant que suppressions, mais celles-ci sont le roi des opérations rares (à bail dans mon système ils sont). A part ça, je ne sais pas comment améliorer cette solution pour le moment.
la source
la source
je fais ça:
1 -> insérer
2 -> supprimer
3 -> mise à jour
la source
la source