Je travaille sur SQL Server 2008 R2.
J'ai un avantage de table qui a un déclencheur AFTER INSERT, UPDATE nommé tiu_benefit .
Je veux écrire une instruction UPDATE pour que cette table mette à jour 1 ligne mais je ne veux pas que son déclencheur se déclenche. Je sais que je peux désactiver le déclencheur avant UPDATE, puis activer le déclencheur après UPDATE:
DISABLE TRIGGER tiu_benefit ON benefit;
GO
UPDATE benefit SET editor = 'srh' where benefit_id = 9876
GO
ENABLE TRIGGER tiu_benefit ON benefit;
GO
Mais ce déclencheur de désactivation et d'activation affectera tous les utilisateurs connectés actuellement. Il est donc possible qu'un autre utilisateur exécute une MISE À JOUR / INSÉRER alors que le déclencheur est désactivé par mon script, ce qui n'est pas bon. C'est pourquoi je veux seulement désactiver et activer le déclencheur pour ma session actuelle. C'est possible? Si oui, dites comment.
Merci
Réponses:
J'ai fait quelques tests à ce sujet et je pense que vous iriez bien si vous exécutez votre processus en une seule transaction.
Lors de mes tests, je n'ai mis en évidence et exécuté
BEGIN TRANSACTION
que leDISABLE TRIGGER
premier. Je puis ouvert une nouvelle (seconde) fenêtre de requête et tenté d'exécuter diverses déclarations DML (SELECT
,INSERT
,UPDATE
DELETE
) contre la table de base. Toutes les tentatives d'accès à la table de base dans la deuxième fenêtre de requête ont attendu les verrous détenus par la fenêtre avec la transaction explicite. Une fois que j'ai validé (ou annulé) ma transaction explicite, la deuxième fenêtre a pu accéder à la table.la source
benefit_id
:)Pour résoudre votre problème, nous devons adopter une approche programmatique du problème. Il y a deux itinéraires que vous pouvez emprunter ici. La raison pour laquelle ces approches sont nécessaires est que vous ne pouvez pas désactiver un déclencheur pour une instruction particulière, il ne peut être désactivé que pour l'intégralité du tableau.
Option 1: Context_Info ()
Samuel Vanga sur MS SQL Tips avait un excellent exemple:
Maintenant, quand Samuel ne veut pas que le déclencheur s'exécute, ils utilisent ceci:
Context_Info
utilise les vues système suivantes pour récupérer des informations concernant la session en cours:sys.dm_exec_requests
sys.dm_exec_sessions
sys.sysprocesses
L'idéologie ici est que la chaîne binaire que vous définissez n'est exposée qu'à la session en cours, donc lorsque le déclencheur s'exécute pendant votre session, il verra la portée et le paramètre variable de la
Context_info
fonction et passera à la partie d'échappement du déclencheur. au lieu.Option 2: Tableau des températures
Itzik Ben-Gan a une excellente solution dans son livre "Inside Microsoft SQL Server 2008 Programmation T-SQL: Programmation T-SQL" qui est également dans son livre T-SQL Querying . Le principal problème avec cela sur la
context_info
fonction est le surdébit mineur de TempDB.Pour gâcher la surprise mais ne pas gâcher l'intrigue des livres (j'ai senti qu'ils valent la peine d'être achetés et lus), vous allez modifier votre déclencheur.
Votre déclencheur doit effectuer une vérification pour une table temporaire. Si la table temporaire existe, le déclencheur doit savoir se terminer et ne pas effectuer les actions.
Dans l'instruction de mise à jour que vous souhaitez effectuer, créez d'abord la table temporaire. Il apparaîtra dans la même transaction que le déclencheur et entraînera le déclencheur à ignorer votre instruction.
Exemple de déclencheur:
Exemple d'instruction de début lorsque vous ne voulez pas que le déclencheur s'exécute:
Mettre tout à fait pour votre exemple:
la source
context_info
utilisationoriginal_login()
pour indiquer au déclencheur de ne jamais s'exécuter si une personne spécifique appuie sur le déclencheur.J'utiliserais l'un
CONTEXT_INFO
ou l' autre ou le plus récentSESSION_CONTEXT
. Les deux sont des valeurs basées sur la session.CONTEXT_INFO
est uneVARBINARY(128)
valeur unique . Celui-ci est disponible depuis au moins SQL Server 2000.CONTEXT_INFO
est visible par tout le mondeVIEW SERVER STATE
car il s'agit d'un champ renvoyé par lesys.dm_exec_sessions
DMV. J'ai déjà utilisé celui-ci et il fonctionne très bien.Définir via SET CONTEXT_INFO
Obtenir via CONTEXT_INFO () ou sys.dm_exec_sessions
Selon le type de valeur que vous stockez
CONTEXT_INFO
, il y a quelques nuances à prendre en compte. Je couvre cela dans le blog suivant:Pourquoi CONTEXT_INFO () ne renvoie-t-il pas la valeur exacte définie par SET CONTEXT_INFO?
Session_context est une paire de
SQL_VARIANT
valeurs clé / valeur . Cela a été introduit dans SQL Server 2016. La séparation des valeurs à des fins différentes est assez agréable. Session_context n'est visible que par la session en cours.Définissez cette valeur via sp_set_session_context
Obtenez cette valeur via SESSION_CONTEXT
Une chose à considérer concernant l'option de table temporaire locale et même l'option désactiver / activer le déclencheur: les deux nécessitent une certaine quantité de verrouillage et d'activité du journal de transfert. Ces deux options augmentent le potentiel de contention, même minime. Les deux options "contextuelles" doivent être plus légères / mémoire uniquement.
la source