Précédent   Forum des professionnels en informatique > Bases de données > MS SQL-Server > Développement
Développement Forum d'entraide sur le Transact-SQL, le CLR, les procédures stockées, les triggers, les requêtes SQL
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 14/09/2011, 11h55   #1
Membre Expert
 
Homme Sylvain Devidal
Chef de projets Générix
Inscription : février 2010
Messages : 1 062
Détails du profil
Informations personnelles :
Nom : Homme Sylvain Devidal
Âge : 33
Localisation : France, Rhône (Rhône Alpes)

Informations professionnelles :
Activité : Chef de projets Générix
Secteur : High Tech - Éditeur de logiciels

Informations forums :
Inscription : février 2010
Messages : 1 062
Points : 1 515
Points : 1 515
Par défaut Trigger et contexte : un exemple ?

Bonjour,

J'ai besoin de créer un trigger dont le comportement sera différent selon une information de contexte.

Ce contexte peut-être différent pour deux batchs qui tournent en //.

Par exemple, dans une PS, je suis en contexte "debug", et dans ce cas, je dois alimenter une table de log en fonction des actions effectuées par le trigger.
Mais dans une autre PS, je suis en mode "release", et dans ce cas, le trigger va se contenter de s'exécuter sans remplir la table de log.

J'ai trouvé qu'on pouvait alimenter une variable "CONTEXT_INFO" et la réutiliser depuis un trigger.

Mais les articles et les exemple de la MSDN ne sont pas très clairs : je veux être certain que si je lance mes deux procédures en même temps, le trigger se comportera comme il doit.

Est-ce qu'il suffit dans la première PS de faire :

Code :
1
2
3
4
 
SET context_info = 'debug';
INSERT INTO matablequideclencheletrigger;
SET context_info = NULL;
Et dans la seconde :
Code :
1
2
3
4
 
SET context_info = 'release';
INSERT INTO matablequideclencheletrigger;
SET context_info = NULL;
Ou si cette variable se comportera comme une variable de session et ne sera pas isolée par scope ?
StringBuilder est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 14/09/2011, 17h07   #2
Membre Expert
 
Homme Sylvain Devidal
Chef de projets Générix
Inscription : février 2010
Messages : 1 062
Détails du profil
Informations personnelles :
Nom : Homme Sylvain Devidal
Âge : 33
Localisation : France, Rhône (Rhône Alpes)

Informations professionnelles :
Activité : Chef de projets Générix
Secteur : High Tech - Éditeur de logiciels

Informations forums :
Inscription : février 2010
Messages : 1 062
Points : 1 515
Points : 1 515
Ca attire les foules c'est fou

Je ne comprends pas pourquoi, context_info ne fait pas du tout ce qu'il est censé faire... Ou tout du moins, il ne fait pas ce qui est décrit dans les exemples que j'ai pu trouver.

Voici un exemple :

Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
 
DROP TRIGGER ins_test;
DROP procedure p_test;
DROP TABLE test;
 
CREATE TABLE test
(
	id int identity NOT NULL PRIMARY KEY,
	nom varchar(50) NOT NULL
);
go
 
CREATE procedure p_test(@nom varchar(50), @mycontext int)
AS
begin
	print 'On initialise le contexte à ' + convert(varchar(6), @mycontext);
	declare @ctx varbinary(128);
	SET @ctx = convert(varbinary(128), @mycontext);
	SET context_info @ctx;
	print 'Pour vérification le contexte à ' + convert(varchar(6), convert(int, @ctx));
 
	print 'On insère quelquechose dans la table, pour lancer le trigger';
	INSERT INTO test (nom) VALUES (@nom);
 
	print 'On repasse le contexte à une valeur par défaut qui soit incomprise par le trigger';
	SET @ctx = convert(varbinary(128), -1);
	SET context_info @ctx;
end;
go
 
CREATE TRIGGER ins_test
ON test  
after INSERT
AS
begin
	declare @ctx int;
	print 'Lancement du trigger';
 
	SET @ctx = convert(int, context_info());
 
	IF @ctx = 1
	begin
		print 'Truc qui se déclenche si context_info = 1';
	end;
 
	print 'Valeur réelle du contexte : ' + convert(varchar(6), @ctx);
end;
go
 
exec dbo.p_test 'Plop', 1;
exec dbo.p_test 'Plop', 2;
exec dbo.p_test 'Plop', 0;
Résultat obtenu :
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
 
ON initialise le contexte à 1
Pour vérification le contexte à 1
ON insère quelquechose dans la TABLE, pour lancer le TRIGGER
Lancement du TRIGGER
Valeur réelle du contexte : 0
 
(1*ligne(s) affectée(s))
ON repasse le contexte à une valeur par défaut qui soit incomprise par le TRIGGER
ON initialise le contexte à 2
Pour vérification le contexte à 2
ON insère quelquechose dans la TABLE, pour lancer le TRIGGER
Lancement du TRIGGER
Valeur réelle du contexte : 0
 
(1*ligne(s) affectée(s))
ON repasse le contexte à une valeur par défaut qui soit incomprise par le TRIGGER
ON initialise le contexte à 0
Pour vérification le contexte à 0
ON insère quelquechose dans la TABLE, pour lancer le TRIGGER
Lancement du TRIGGER
Valeur réelle du contexte : 0
 
(1*ligne(s) affectée(s))
ON repasse le contexte à une valeur par défaut qui soit incomprise par le TRIGGER
=> Dans le trigger, le context_info est toujours à 0 !


Je me suis basé sur cet article :
http://jasondentler.com/blog/2010/01...fun-and-audit/

PS : Ceci dit, je n'aime pas trop ce que je lis dans l'article... Moi j'aurais plutôt besoin d'une variable dont le scope reste au niveau de la fonction appelante. C'est à dire un contexte local à la procédure qui déclence le trigger. Ca existe ? Ou si je vais devoir coder une using à gaz pour le reproduire ?
StringBuilder est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 15/09/2011, 15h08   #3
Responsable SQL Server

 
Avatar de mikedavem
 
Homme David BARBARIN
Expert SQL Server
Inscription : août 2005
Messages : 3 724
Détails du profil
Informations personnelles :
Nom : Homme David BARBARIN
Localisation : France, Haute Savoie (Rhône Alpes)

Informations professionnelles :
Activité : Expert SQL Server
Secteur : Conseil

Informations forums :
Inscription : août 2005
Messages : 3 724
Points : 6 848
Points : 6 848
Remplacez votre variable de type INT en CHAR(1) par exemple :

Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
DROP TRIGGER ins_test;
DROP procedure p_test;
DROP TABLE test;
 
CREATE TABLE test
(
	id int identity NOT NULL PRIMARY KEY,
	nom varchar(50) NOT NULL
);
go
 
CREATE procedure p_test(@nom varchar(50), @mycontext CHAR(1))
AS
begin
	print 'On initialise le contexte à ' + convert(CHAR(1), @mycontext);
	declare @ctx varbinary(128);
	SET @ctx = convert(varbinary(128), @mycontext);
	SET context_info @ctx;
	print 'Pour vérification le contexte à ' + convert(CHAR(1), @ctx);
 
	print 'On insère quelquechose dans la table, pour lancer le trigger';
	INSERT INTO test (nom) VALUES (@nom);
 
	print 'On repasse le contexte à une valeur par défaut qui soit incomprise par le trigger';
	SET @ctx = convert(varbinary(128), -1);
	SET context_info @ctx;
end;
go
 
CREATE TRIGGER ins_test
ON test  
after INSERT
AS
begin
	declare @ctx CHAR(1);
	print 'Lancement du trigger';
 
	SET @ctx = convert(CHAR(1), context_info());
 
	IF @ctx = '1'
	begin
		print 'Truc qui se déclenche si context_info = 1';
	end;
 
	print 'Valeur réelle du contexte : ' + convert(CHAR(1), @ctx);
end;
go
Citation:
Résultat :

On initialise le contexte à 1
Pour vérification le contexte à 1
On insère quelquechose dans la table, pour lancer le trigger
Lancement du trigger
Truc qui se déclenche si context_info = 1
Valeur réelle du contexte : 1

(1 row(s) affected)
On repasse le contexte à une valeur par défaut qui soit incomprise par le trigger
On initialise le contexte à 2
Pour vérification le contexte à 2
On insère quelquechose dans la table, pour lancer le trigger
Lancement du trigger
Valeur réelle du contexte : 2

(1 row(s) affected)
On repasse le contexte à une valeur par défaut qui soit incomprise par le trigger
On initialise le contexte à 0
Pour vérification le contexte à 0
On insère quelquechose dans la table, pour lancer le trigger
Lancement du trigger
Valeur réelle du contexte : 0
++
mikedavem est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 15/09/2011, 17h52   #4
Membre Expert
 
Homme Sylvain Devidal
Chef de projets Générix
Inscription : février 2010
Messages : 1 062
Détails du profil
Informations personnelles :
Nom : Homme Sylvain Devidal
Âge : 33
Localisation : France, Rhône (Rhône Alpes)

Informations professionnelles :
Activité : Chef de projets Générix
Secteur : High Tech - Éditeur de logiciels

Informations forums :
Inscription : février 2010
Messages : 1 062
Points : 1 515
Points : 1 515
GRMPF !

J'hallucine, c'était juste ça ?

Faudra qu'on m'explique pourquoi il aime pas un INT et préfère un CHAR mais bon

Merci en tout cas, j'aurais jamais pensé à essayer ça !

PS : Entre temps, j'ai finalement réétudié mon problème pour m'en passer. Après tout, si sémantiquement on ne peut pas passer de variables à un trigger, c'est qu'il doit y avoir une bonne raison, du coup j'ai changer de place certaines traitements pour les faire en dehors du trigger.
StringBuilder est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 01h46.


 
 
 
 
Partenaires

Hébergement Web