{"id":181,"date":"2010-06-22T20:51:00","date_gmt":"2010-06-22T19:51:00","guid":{"rendered":"http:\/\/csopro.de\/biblog\/2010\/06\/begin-try-in-sql-batch-statements\/"},"modified":"2010-06-22T20:51:00","modified_gmt":"2010-06-22T19:51:00","slug":"begin-try-in-sql-batch-statements","status":"publish","type":"post","link":"https:\/\/www.csopro.de\/biblog\/2010\/06\/begin-try-in-sql-batch-statements\/","title":{"rendered":"begin try in SQL-Batch-Statements"},"content":{"rendered":"<p>Es kommt \u00f6fter vor, dass man im Batch mehrere SQL-Statements ausf\u00fchren m\u00f6chte, sei es in einer Stored Procedure oder im Execute SQL-Task von SSIS.<\/p>\n<p>Meistens hat man folgende Anforderung:<\/p>\n<p>L\u00e4uft ein Statement auf einen Fehler, soll ein Rollback der Statements gemacht werden. Au\u00dferdem soll nat\u00fcrlich dem aufrufenden System der Fehler gemeldet werden.<\/p>\n<p>L\u00e4sst man einen Batch einfach so laufen, wird dieses Ziel nicht erreicht, da im Fehlerfall auch die Statements nach dem Statement, das den Fehler verursacht, ausgef\u00fchrt werden.<\/p>\n<p>Beispiel:<\/p>\n<blockquote>\n<p>set nocount on<br \/>\nselect 1<br \/>\nselect 1\/0<br \/>\nselect 2<\/p>\n<\/blockquote>\n<p>liefert:<\/p>\n<blockquote>\n<p>\n&#8212;&#8212;&#8212;&#8211;<br \/>\n1<\/p>\n<p>\n&#8212;&#8212;&#8212;&#8211;<br \/>\nMsg 8134, Level 16, State 1, Line 3<br \/>\nDivide by zero error encountered.<\/p>\n<p>\n&#8212;&#8212;&#8212;&#8211;<br \/>\n2<\/p>\n<\/blockquote>\n<p>In Versionen vor SQL Server 2005 musste man die Error-Variable auslesen, etwa so:<\/p>\n<blockquote>\n<p>set nocount on<br \/>\ndeclare @fehler as int<br \/>\nset @fehler = 0<br \/>\nselect 1<br \/>\nset @fehler = @fehler + @@error<br \/>\nselect 1\/0<br \/>\nset @fehler = @fehler + @@error<br \/>\nselect 2<br \/>\nset @fehler = @fehler + @@error<br \/>\nif @fehler&gt;0 begin<br \/>\n print &#8218;Ein Fehler ist aufgetreten&#8216;<br \/>\nend<\/p>\n<\/blockquote>\n<p>was folgendes Ergebnis liefert:<\/p>\n<blockquote>\n<p>\n&#8212;&#8212;&#8212;&#8211;<br \/>\n1<\/p>\n<p>\n&#8212;&#8212;&#8212;&#8211;<br \/>\nMsg 8134, Level 16, State 1, Line 6<br \/>\nDivide by zero error encountered.<\/p>\n<p>\n&#8212;&#8212;&#8212;&#8211;<br \/>\n2<\/p>\n<p>Ein Fehler ist aufgetreten<\/p>\n<\/blockquote>\n<p>Das Problem ist, man muss die Zeile &#8222;set @fehler = @fehler + @@error&#8220; nach jedem Statement schreiben, da sie nach jedem (!) Statement zur\u00fcckgesetzt wird.<\/p>\n<p>Leichter geht das in SQL 2005 mit begin try &#8230; end try &#8211; angelehnt an Konstrukte aus Programmiersprachen wie C#:<\/p>\n<blockquote>\n<p>set nocount on<br \/>\nbegin try<\/p>\n<p>select 1<br \/>\nselect 1\/0<br \/>\nselect 2<\/p>\n<p>end try<br \/>\nbegin catch<br \/>\n print &#8218;Ein Fehler aufgetreten&#8216;<br \/>\nend catch<\/p>\n<\/blockquote>\n<p>Am Ergebnis<\/p>\n<blockquote>\n<p>\n&#8212;&#8212;&#8212;&#8211;<br \/>\n1<\/p>\n<p>\n&#8212;&#8212;&#8212;&#8211;<\/p>\n<p>Ein Fehler aufgetreten<\/p>\n<\/blockquote>\n<p>sieht man, dass nach dem fehlerhaften Statement die Bearbeitung beendet wird.<\/p>\n<p>Nun fehlen nur noch 2 Anforderungen:<\/p>\n<p>Dass keine Datenmanipulation statt findet, erreicht man \u00fcber eine Transaktion, die im catch-Block zur\u00fcckgerollt (rollback) wird.<\/p>\n<p>Dass der Aufruf dennoch den Fehler mitbekommt, erreicht man \u00fcber einen raiserror.<\/p>\n<p>Das fertige Skript sieht dann so aus:<\/p>\n<blockquote>\n<p>set nocount on<\/p>\n<p>begin tran<br \/>\nbegin try<\/p>\n<p>\/* hier die eigentlichen SQL-Statements schreiben *\/<br \/>\nselect 1<br \/>\nselect 1\/0<br \/>\nselect 2<\/p>\n<p>end try<br \/>\nbegin catch<br \/>\nif @@trancount &gt; 0 begin<br \/>\n        rollback tran<br \/>\nend<br \/>\ndeclare @fehler_text nvarchar(4000)<br \/>\nset @fehler_text = ERROR_MESSAGE()<br \/>\ndeclare @fehler_severity int<br \/>\nset @fehler_severity = ERROR_SEVERITY()<br \/>\ndeclare @fehler_state int<br \/>\nset @fehler_state = ERROR_STATE()<br \/>\nRAISERROR (@fehler_text, &#8212; Message text.<br \/>\n        @fehler_severity, &#8212; Severity.<br \/>\n        @fehler_state &#8212; State.<br \/>\n)<\/p>\n<p>end catch<br \/>\nif @@trancount &gt; 0 begin<br \/>\n        commit tran<br \/>\nend<\/p>\n<\/blockquote>\n","protected":false},"excerpt":{"rendered":"<p>Es kommt \u00f6fter vor, dass man im Batch mehrere SQL-Statements ausf\u00fchren m\u00f6chte, sei es in einer Stored Procedure oder im Execute SQL-Task von SSIS. Meistens hat man folgende Anforderung: L\u00e4uft ein Statement auf einen Fehler, soll ein Rollback der Statements gemacht werden. Au\u00dferdem soll nat\u00fcrlich dem aufrufenden System der Fehler gemeldet werden. L\u00e4sst man einen &hellip; <a href=\"https:\/\/www.csopro.de\/biblog\/2010\/06\/begin-try-in-sql-batch-statements\/\" class=\"more-link\"><span class=\"screen-reader-text\">begin try in SQL-Batch-Statements<\/span> weiterlesen <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[10,12],"tags":[],"class_list":["post-181","post","type-post","status-publish","format-standard","hentry","category-integrationservices","category-sqlserver"],"_links":{"self":[{"href":"https:\/\/www.csopro.de\/biblog\/wp-json\/wp\/v2\/posts\/181","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.csopro.de\/biblog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.csopro.de\/biblog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.csopro.de\/biblog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.csopro.de\/biblog\/wp-json\/wp\/v2\/comments?post=181"}],"version-history":[{"count":0,"href":"https:\/\/www.csopro.de\/biblog\/wp-json\/wp\/v2\/posts\/181\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.csopro.de\/biblog\/wp-json\/wp\/v2\/media?parent=181"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.csopro.de\/biblog\/wp-json\/wp\/v2\/categories?post=181"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.csopro.de\/biblog\/wp-json\/wp\/v2\/tags?post=181"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}