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 20/06/2008, 12h41   #1
Invité de passage
 
Inscription : mars 2008
Messages : 29
Détails du profil
Informations forums :
Inscription : mars 2008
Messages : 29
Points : 4
Points : 4
Par défaut Cannot Rollback Transaction

Bonjour,
J'ai créé un trigger instead of insert sur une vue multitable.
Cela concerne l'insertion de project de client et de composant.

Les 2 tables en questions ici sont:
CUSTOMER : id_customer, customer_name
PROJECT: id_project, project_name, id_customer#

Voilà le bout de code de mon trigger qui pose problème.
Code sql :
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
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
BEGIN TRANSACTION CHECK_AND_INSERT_PROJECT
 
 
 
DECLARE @id_project int
 
		IF EXISTS (SELECT PROJECT.name 
						FROM PROJECT 
						JOIN INSERTED 
						ON PROJECT.name = INSERTED.project_name
						JOIN CUSTOMER
						ON PROJECT.id_customer != @id_customer
						WHERE (NOT (INSERTED.project_name LIKE N'TAM_%')) )
 
						BEGIN 
							PRINT 'Wrong customer_name for this project. Please check...'
							DECLARE @bin_check bit
							SET @bin_check = 1
							--ROLLBACK TRANSACTION CHECK_AND_INSERT_PROJECT
						END
 
							ELSE
 
							BEGIN			
										IF EXISTS (SELECT PROJECT.name 
													FROM PROJECT 
													JOIN INSERTED 
													ON PROJECT.name = INSERTED.project_name
													JOIN CUSTOMER
													ON PROJECT.id_customer = @id_customer)
 
														BEGIN
																		SET @id_project = (SELECT PROJECT.id_project 
																							FROM PROJECT 
																							JOIN INSERTED 
																							ON PROJECT.name = INSERTED.project_name
																							JOIN CUSTOMER 
																							ON PROJECT.id_customer = CUSTOMER.id_customer)
 
																					PRINT 'Le nom de projet existe pour numéro de client ci-dessus :'
																					PRINT (@id_project)
 
														END	
 
 
														ELSE
 
															BEGIN 
																	DECLARE @project_name nvarchar(255)
																	SET @project_name = (SELECT project_name FROM INSERTED)
 
																	INSERT INTO PROJECT (PROJECT.name, PROJECT.id_customer)
																	VALUES (@project_name, @id_customer)
																	SET @id_project = SCOPE_IDENTITY()
 
 
 
																	PRINT 'Le projet n''existe pas. Insertion d''nouveau projet avec le numéro de client '
																	PRINT (@id_project)	
																	PRINT 'avec le numéro de client'
																	PRINT (@id_customer)
 
															END
 
 
 
END	
 
IF @bin_check = 1 
ROLLBACK TRANSACTION CHECK_AND_INSERT_PROJECT
ELSE
COMMIT TRANSACTION CHECK_AND_INSERT_PROJECT

En gros ma transaction vérifie si un nom de project n'a qu'un seul et unique numéro de client sauf pour les noms de projets du type like'TAM_%'

Quand j'insere des données invalides voilà ce que j'ai sur la sortie:
Code :
1
2
3
4
5
6
7
(1 row(s) affected)
Le client existe pas -> Insertion nouveau client :
4451
Wrong customer_name FOR this project. Please CHECK...
Msg 6401, Level 16, State 1, Procedure test_insert, Line 131
Cannot roll back CHECK_AND_INSERT_PROJECT. No transaction OR savepoint of that name was found.
The statement has been terminated.
Je suis débutant en TSQL et je suis pas sûr de bien comprendre les différentes manières de réagir du moteur entre un bloc d'instruction BEGIN...END et une transaction.

Voilà, merci d'avance, bon appétit!
qlaimand est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 24/06/2008, 10h03   #2
Membre Expert
 
Inscription : juin 2007
Messages : 1 056
Détails du profil
Informations forums :
Inscription : juin 2007
Messages : 1 056
Points : 1 078
Points : 1 078
bonjour,

je pense que le begin transaction devrait être hors du trigger : en général on gère la transaction en amont, dans le code qui met à jour les enregistrements de la table qui déclenchera le trigger. Il n'y a qu'à mettre un rollback transaction <name>, <name> correspondant à la transaction débutée avant le déclenchement du trigger...
__________________
Emmanuel T.
kagemaru est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 25/06/2008, 16h09   #3
Rédacteur/Modérateur

 
Avatar de SQLpro
 
Homme Frédéric BROUARD
Expert SGBDR & SQL
Inscription : mai 2002
Messages : 10 959
Détails du profil
Informations personnelles :
Nom : Homme Frédéric BROUARD
Localisation : France

Informations professionnelles :
Activité : Expert SGBDR & SQL
Secteur : Conseil

Informations forums :
Inscription : mai 2002
Messages : 10 959
Points : 17 792
Points : 17 792
Un trigger est déjà à l'intérieur d'une transaction même si vous ne l'avez par explicitement lancée (transaction implicite). Commencer votre trigger par une transaction n'a donc aucun sens et SQL Server ne s'y retrouve plus parce que les transactions imbriquées cela n'existe pas...

A +
__________________
Frédéric Brouard - SQLpro - ARCHITECTE DE DONNÉES - expert SGBDR et langage SQL
Site sur les SGBD relationnels et le langage SQL: http://sqlpro.developpez.com/
Expert Microsoft SQL Server - M.V.P. (Most valuable Professional) MS Corp.
Blog SQL, SQL Server, modélisation données : http://blog.developpez.com/sqlpro
http://www.sqlspot.com : modélisation, conseils, audit, optimisation, formation
* * * * * Enseignant CNAM PACA - ISEN Toulon - CESI Aix en Provence * * * * *
SQLpro 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 02h53.


 
 
 
 
Partenaires

Hébergement Web