De sortie et de retour en arrière tout en script en cas d'erreur
J'ai un script TSQL qui fait beaucoup d'ajustements de la structure de la base de données mais ce n'est pas vraiment sûr que de laisser aller de travers quand quelque chose tombe en panne.
à mettre les choses au clair:
- à l'aide de MS SQL 2005
- ce n'est PAS une procédure stockée, juste un fichier de script (.sql)
ce que j'ai, c'est quelque chose dans l'ordre suivant
BEGIN TRANSACTION
ALTER Stuff
GO
CREATE New Stuff
GO
DROP Old Stuff
GO
IF @@ERROR != 0
BEGIN
PRINT 'Errors Found ... Rolling back'
ROLLBACK TRANSACTION
RETURN
END
ELSE
PRINT 'No Errors ... Committing changes'
COMMIT TRANSACTION
juste pour illustrer ce que je suis en train de travailler avec ... ne peut pas aller dans les détails
maintenant, le problème ...
Quand je introduire une erreur (pour tester si les choses se roula en arrière), j'obtiens une déclaration que le ROLLBACK TRANSACTION ne pouvait pas trouver un correspondant de COMMENCER l'OPÉRATION.
Cela me mène à croire que quelque chose de VRAIMENT mauvais et que la transaction a déjà été tué.
ce que j'ai aussi remarqué, c'est que le script n'a pas de quitter complètement en erreur et N'a donc essayez d'exécuter chaque instruction après l'erreur s'est produite. (Je l'ai remarqué lorsque de nouvelles tables ont montré jusqu'à quand je ne m'y attendais pas, car il doit avoir rollbacked)
OriginalL'auteur Jan W. | 2010-05-26
Vous devez vous connecter pour publier un commentaire.
Lorsque l'erreur se produit, la transaction est annulée automatiquement, et le lot en cours est annulée.
L'exécution se poursuit dans le lot suivant, cependant. Donc tous les trucs dans les lots après l'erreur est exécuté. Et puis, quand vous vérifiez les erreurs plus tard, vous essayez pour la restauration d'un déjà roulé sur le dos de la transaction.
Aussi, pour arrêter le script en entier, pas seulement le lot en cours, vous devez utiliser:
Voir ma réponse ici pour plus de détails sur celle-ci.
De sorte que vous devez vérifier pour
@error
après chaque lot, je pense que quelque chose comme cela devrait fonctionner:set noexec on
est un truc intéressant, doivent se rappeler que.Est-ce de travailler avec un serveur de transaction tels que
DROP LOGIN
? Je veux changer de domaine d'un compte de connexion appartient et je suis tomber à partir de bases de données, mais besoin de recréer tout en veillant à ce que RIEN n'est tombé si CHAQUE transaction est validée avec succès. Ce résultat serait mal mappé autorisations, etc. et ce serait une catastrophe.Il semble que le travail: j'ai juste couru un script
begin transaction; drop login [pc\user]; raiserror('Script failed', 20, -1) with log
- la connexion n'a pas été supprimée (assurez-vous que vous êtes connecté en tant quesa
avant de le faire bien, ou raiserror échoue et le script va continuer!)Qui ne fonctionne que si truc est une instruction unique. Le
@@ERROR
retourne un seul résultat de la dernière instruction exécutée, donc si truc se compose de plusieurs états, seulement une erreur sur la dernière déclaration de provoquer ce genre d'erreur de manipulation à effectuer.TRY...CATCH
est mieux.OriginalL'auteur Blorgbeard
Essayez de RETOUR. cette sortie du script ou de la procédure et de ne pas exécuter les instructions suivantes. Vous pouvez l'utiliser en conjonction avec COMMENCER, de RESTAURATION et de COMMETTRE des déclarations de TRANSACTION à annuler les dommages de données:
OriginalL'auteur A___
Je n'ai pas utilisé le raiseerror solution, parce qu'elle a échoué car je n'ai pas disposer des autorisations d'administrateur. J'ai étendu la noexec on/off de la solution à l'opération de manutention comme suit:
Apparemment le compilateur "comprend" la @terminé variable dans le SI, même si il y avait une erreur et que l'exécution a été désactivé. Toutefois, la valeur est définie sur 1 que si l'exécution n'a pas été désactivé. Donc je peux bien commit ou rollback de la transaction en conséquence.
OriginalL'auteur Tz_
Vous pouvez essayer quelque chose comme ça... Si vous utilisez le bloc Try... Le niveau d'erreur 16, (ou la plupart d'erreur d'application), transfère immédiatement le contrôle pour le bloc CATCH sans exécuter d'autres déclarations dans le bloc try...
Espère que cela aide...
GO
états à l'intérieur d'unTRY-CATCH
: msdn.microsoft.com/en-us/library/ms179296.aspxOriginalL'auteur The King
OriginalL'auteur Edward Olamisan