[TSQL] Trigger, Execute & Enterprise Manager

Trigger, Execute & Enterprise Manager [TSQL] - SQL/NoSQL - Programmation

Marsh Posté le 15-12-2005 à 14:52:56    

J'ai un souci sous Enterprise Manager, que je vais vous exposer vite fait avec un exemple. :o
 
J'ai un trigger sur une table, qui se lance sur l'évènement Update.
Dedans j'ai ce bout de code (en gros :o ).
 

Code :
  1. If Exists
  2. (
  3.    Select 1
  4.    From [MaTable]
  5. )
  6. Select 1
  7. Raiserror('erreur je_lance_une_erreur', 16, 1)


 
Sous l'analyseur de requête, quand j'update un enregistrement de la table, ça me lance bien l'erreur du Raiserror (le code continue).
Sous Enterprise Manager, quand j'update un enregistrement de la table, ça me monte bien un message d'erreur, en m'indiquant le message du Raiserror.
 

Code :
  1. Set @strRequete='If Exists (Select 1 From [MaTable]) Select 1'
  2. Execute(@strRequete)
  3. Raiserror('erreur je_lance_une_erreur', 16, 1)


 
Sous l'analyseur de requête, l'erreur du Raiserror se lance bien.
Sous Enterprise Manager, plus aucun message d'erreur ne s'affiche, ça se contente de rollbacker automatiquement la transaction (graphiquement on perd la modification faite dans le champ).
 
Comment ça se fait ?  [:ryoandr]
C'est un bug absolument génant, voire bloquant. J'ai absolument besoin de pouvoir afficher des messages d'erreur sous Enterprise Manager.
 
Note: je précise que je suis obligé de passer par une requête construite & donc un Execute, car la vraie requête est le résultat de concaténation de variables & de résultats de fonctions.


---------------
Everyone's dancing furiously! - L'Europe, j'en ai plein les godasses, l'Europe, ça me file la chiasse
Reply

Marsh Posté le 15-12-2005 à 14:52:56   

Reply

Marsh Posté le 15-12-2005 à 14:58:56    

salut.
 
étrange comme problème en effet.
 
regarde la doc à propos du "execute", il y a en effet une série de limitations plus ou moins improtantes.
 
 
par conre, attention aux "execute". dans la plupart des cas, même si ça paraît impossible à première vue, on peut s'en passer sans aucun problème !

Reply

Marsh Posté le 15-12-2005 à 14:59:27    

je serais curieux de voir comme tu construis te requête :)

Reply

Marsh Posté le 15-12-2005 à 15:08:23    

Je suis pas un grand fan des requêtes construites, mais là je vois pas comment faire autrement. :o
 

Code :
  1. Set @strRequete='If Exists (Select 1 From ' + @strPrefixe + 'SYSOBJECTS'
  2. Set @strRequete=@strRequete+' Where NAME= '''+ @strTable + ''''
  3. Set @strRequete=@strRequete+' And TYPE=''U'') Select 1'
  4. Exec(@strRequete)


 
@strPrefixe est calculé en amont par une fonction, qui elle même va chercher dans une table une donnée qui peut changer à tout moment, un chemin de base de données [serveur].[BD].[dbo].
Quant à @strTable, on pourrait effectivement s'en passer, mais l'utiliser amélioreme grandement la lisibilité du code & surtout sa maintenance (avoir à saisir X fois le nom d'une table, c'est un peu cracra & chiant à maintenir).


---------------
Everyone's dancing furiously! - L'Europe, j'en ai plein les godasses, l'Europe, ça me file la chiasse
Reply

Marsh Posté le 15-12-2005 à 15:20:03    

Set @strRequete=@strRequete+' Where NAME= @strTable and type = ''U'''
 
-> Déjà, ça va va marcher à cause de ton execute.
 
fait chier, je trouve plus la syntaxe pour se connecter à une autre base.
ceci dit, tu peux toujours utilise ça :
openrowset()
-> je ne sais pas s'il a le même problème que execute

Reply

Marsh Posté le 15-12-2005 à 15:27:39    

Ma requête est bonne, t'as oublié des ouvetures/fermetures de chaine en cours de route. :p
 
Pour OpenRowSet, je peux pas m'en servir, j'ai pas les infos de connexion, j'ai juste le nom du serveur et le nom de la BD cible. (ça me pose pas de problème étant donné que les serveurs sont liés)


---------------
Everyone's dancing furiously! - L'Europe, j'en ai plein les godasses, l'Europe, ça me file la chiasse
Reply

Marsh Posté le 15-12-2005 à 15:29:50    

LightKyle a écrit :

Ma requête est bonne, t'as oublié des ouvetures/fermetures de chaine en cours de route. :p
 
Pour OpenRowSet, je peux pas m'en servir, j'ai pas les infos de connexion, j'ai juste le nom du serveur et le nom de la BD cible. (ça me pose pas de problème étant donné que les serveurs sont liés)


j'ai pas dit que ça marchais pas tes guillements en folie, j'ai juste dis que tu pouvais t'en passer parceque c'est moche et lent ;)
 
sinon, ouais, en effet, c'est la plait ton bidule. mais il doit bien y avoir une instruction qui permet de se connecter à une base et un serveur... faut trouver laquelle :spamafote:

Reply

Marsh Posté le 15-12-2005 à 15:30:44    

enfin, on s'écarte du sujet, regarde déjà la doc à propos des limitation du exec, je sais qu'il y a une histoire de scope qui est un peu chiadée

Reply

Marsh Posté le 15-12-2005 à 15:46:26    

C'est pas plutot un problème avec Enterprise Manager ?
 
Le Exec marche; sans le Raiserror que j'ai mis pour vérifier la gestion des erreurs, le trigger se passe sans souci & marche pile comme il faut.


---------------
Everyone's dancing furiously! - L'Europe, j'en ai plein les godasses, l'Europe, ça me file la chiasse
Reply

Marsh Posté le 15-12-2005 à 15:48:02    

j'ai dû zapper un truc : tu executes comment ton raiseerror depuis entreprise manager ?

Reply

Marsh Posté le 15-12-2005 à 15:48:02   

Reply

Marsh Posté le 15-12-2005 à 15:50:47    

Le Raiserror est dans le trigger. Trigger que je lance dans Enterprise Manager en updatant des données sur la table du trigger.


---------------
Everyone's dancing furiously! - L'Europe, j'en ai plein les godasses, l'Europe, ça me file la chiasse
Reply

Marsh Posté le 15-12-2005 à 15:52:40    

ok. mais alors pkoi tu dis que dans le premier cas, ça marche avec les deux,et pas le second, je panne rien en fait :D

Reply

Marsh Posté le 15-12-2005 à 15:54:25    

sinon, fait ça :
 
str = 'if exists ...
go
raiseerror()'
 
(tu noteras les sauts de ligne sans fermer les ')
 
ça devrait marcher

Reply

Marsh Posté le 15-12-2005 à 16:04:27    

Tu veux dire que je dois mettre le Raiserror dans la requête construite ?
 
Je précise que j'utilise un Raiserror pour garder mon code propre, mais si j'introduit une erreur dans la requête construite (genre je fais un 'select 1 from toto'), le résultat est le même, rollback sans message d'erreur dans Enterprise Manager.


---------------
Everyone's dancing furiously! - L'Europe, j'en ai plein les godasses, l'Europe, ça me file la chiasse
Reply

Marsh Posté le 15-12-2005 à 16:09:17    

Je vais résumer simplement. [:aloy]
 
Si je fais dans mon trigger

Code :
  1. Select 1 From Toto


Enterprise Manager me remonte une erreur, du genre "invalid object name Toto"
 
Si je fais

Code :
  1. @strRequete = 'Select 1 From Toto'
  2. Exec(@strRequete)


Enterprise Manager ne remonte pas d'erreur, il se contente d'annuler la modif que j'ai fait sur le champ pour lancer le trigger.
 
Dans les 2 cas là, l'analyseur de requête me remonte à chaque fois l'erreur.


Message édité par LightKyle le 15-12-2005 à 16:10:39

---------------
Everyone's dancing furiously! - L'Europe, j'en ai plein les godasses, l'Europe, ça me file la chiasse
Reply

Marsh Posté le 15-12-2005 à 16:19:11    

ok. ben... c'est chelou :D

Reply

Marsh Posté le 18-12-2005 à 14:19:10    

Bon je viens de faire un test sur un SQL Server fraichement installé, config par défaut (je suis pas admin SQL Server, juste développeur, je vais éviter de tout casser [:tinostar] ).
Ca plante exactement pareil.
 


 raiserror('erreur perso', 16, 1)
 if @@ERROR <> 0
  Rollback Tran


 
-> Enterprise Manager me sort bien une erreur.
 


 exec('select 1')
 raiserror('erreur perso', 16, 1)
 if @@ERROR <> 0
  Rollback Tran


 
-> Enterprise Manager affiche plus rien comme erreur. [:tinostar]


Message édité par LightKyle le 18-12-2005 à 14:19:32

---------------
Everyone's dancing furiously! - L'Europe, j'en ai plein les godasses, l'Europe, ça me file la chiasse
Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed