USE pubs
SELECT 'Before BEGIN TRAN', TRANCOUNT -- The value of
TRANCOUNT is 0
BEGIN TRAN
SELECT 'After BEGIN TRAN', TRANCOUNT -- The value of
TRANCOUNT is 1
DELETE sales
BEGIN TRAN nested
SELECT 'After BEGIN TRAN nested', TRANCOUNT
-- The value of
TRANCOUNT is 2
DELETE titleauthor
COMMIT TRAN nested
Does nothing except decrement the value of TRANCOUNT
SELECT 'After COMMIT TRAN nested',
TRANCOUNT
The value of TRANCOUNT is 1
ROLLBACK TRAN
SELECT 'After ROLLBACK TRAN',
TRANCOUNT The value of TRANCOUNT is 0
-- because ROLLBACK TRAN always rolls back all transactions and sets
--
TRANCOUNT to 0.
SELECT TOP 5 au_id FROM titleauthor
USE pubs
SELECT 'Before BEGIN TRAN', TRANCOUNT -- The value of
TRANCOUNT is 0
BEGIN TRAN
SELECT 'After BEGIN TRAN', TRANCOUNT -- The value of
TRANCOUNT is 1
DELETE sales
BEGIN TRAN nested
SELECT 'After BEGIN TRAN nested', TRANCOUNT
-- The value of
TRANCOUNT is 2
DELETE titleauthor
ROLLBACK TRAN
SELECT 'After COMMIT TRAN nested', TRANCOUNT
-- The value of
TRANCOUNT is 0 because
ROLLBACK TRAN always rolls back all transactions and sets TRANCOUNT
-- to 0.
IF (
TRANCOUNT > 0) BEGIN
COMMIT TRAN Never makes it here cause of the ROLLBACK
SELECT 'After COMMIT TRAN', TRANCOUNT
END
SELECT TOP 5 au_id FROM titleauthor
</code>
{br}
In diesem Beispiel erreicht die Ausführung niemals den '''COMMIT TRAN''' auf Grund der '''ROLLBACK TRAN''', sie macht alle Transaktionen rückgängig die zur Zeit ausgeführt werden und setzt den '''TRANCOUNT''' wieder auf '''0'''. Sofern '''ROLLBACK TRAN''' ohne Sicherungspunkt ausgeführt wird, wird '''ROLLBACK TRAN''' alle Transaktionen rückgängig machen und den '''TRANCOUNT''' wieder auf '''0''' setzen. Egal in welchem Zusammenhang sie aufgerufen wird.{br}
{br}
{TOP}
{br}
{br}
[anchor|#4]
==Save TRAN und Save Points==
Savepoints bieten einen Vorgang um Teile einer Transaktion rückgängig zu machen. Der Benutzer kann einen Savepoint oder eine Markierung in einer Transaktion setzen. Der Savepoint definiert einen Bereich zu der die Transaktion zurückkehren kann, wenn ein Abschnitt der Transaktion bedingungsweise abgebrochen wird. Der SQL Server bietet Ihnen die Möglichkeit einen Savepoint mit Hilfe der '''SAVE TRAN''' zu setzen, welche den Wert des '''TRANCOUNT''' nicht beeinflusst. Ein Rückschritt zu einem Savepoint (nicht einer Transaktion) beeinflusst den Wert der '''TRANCOUNT''' ebenfalls nicht. Allerdings muss das '''ROLLBACK''' explizit den Namen des Savepoints beinhalten, sonst wird die komplett Transaktion rückgängig gemacht.{br}
{br}
Das folgende Skript zeigt wie man Savepoints benutzt:{br}
{br}
<code sql>USE pubs
SELECT 'Before BEGIN TRAN main',
TRANCOUNT
The value of TRANCOUNT is 0
BEGIN TRAN main
SELECT 'After BEGIN TRAN main',
TRANCOUNT
The value of TRANCOUNT is 1
DELETE sales
SAVE TRAN sales -- Mark a save point
SELECT 'After SAVE TRAN sales',
TRANCOUNT
The value of TRANCOUNT is still 1
BEGIN TRAN nested
SELECT 'After BEGIN TRAN nested',
TRANCOUNT
The value of TRANCOUNT is 2
DELETE titleauthor
SAVE TRAN titleauthor -- Mark a save point
SELECT 'After SAVE TRAN titleauthor',
TRANCOUNT
The value of TRANCOUNT is still 2
ROLLBACK TRAN sales
SELECT 'After ROLLBACK TRAN sales',
TRANCOUNT
The value of TRANCOUNT is still 2
SELECT TOP 5 au_id FROM titleauthor
IF (
TRANCOUNT > 0) BEGIN
ROLLBACK TRAN
SELECT 'AFTER ROLLBACK TRAN', TRANCOUNT
-- The value of
TRANCOUNT is 0 because
ROLLBACK TRAN always rolls back all transactions and sets TRANCOUNT
-- to 0.
END
SELECT TOP 5 au_id FROM titleauthor</code>{br}
{TOP}
{br}
{br}
[anchor|#5]
==Error Handling==
Die hier gezeigten Beispiele sind spezifisch für Stored Procedures, da sie die gewünschte Methode sind um mit einer Datenbank zu interagieren. Wird ein Fehler in einer Stored Procedure gefunden, ist das Beste was Sie machen können die sequentielle Ausführung des Codes zu stoppen und{br}
{br}
* entweder in ein anderes Code Segment der Prozedur zu springen (abzweigen)
* oder die Kontrolle wieder an die aufrufende Applikation zurückgeben.
{br}
Die automatische Variable '''ERROR''' wird benutzt um das Error Handling auszuführen. Sie beinhaltet die Fehler ID die von der letzten ausgeführten SQL Anweisung des Benutzers. Wenn eine Anweisung erfolgreich ausgeführt wird ist der Wert der '''ERROR''' Variable '''0'''. Um festzulegen ob eine Anweisung erfolgreich ausgeführt wurde wird eine '''IF''' Anweisung direkt nach der Ausführung des Statements ausgeführt um den Wert der '''ERROR''' Variable zu prüfen. Es ist unerlässlich die '''ERROR''' Variable nach der Ausführung eines Statements zu prüfen, weil der Wert nach der erfolgreichen Ausführung des nächsten Statements wieder auf '''0''' gesetzt wird. Tritt ein abfangbarer Fehler auf hat '''ERROR''' einen Wert größer '''0'''. Der SQL Server setzt den Wert nach jedem erfolgreichen Befehl wieder auf '''0''', d.h. sie müssen den Fehlerwert sofort erfassen. Meistens testen Sie die '''ERROR''' Variable auf Änderungen nach jeder '''INSERT''', '''UPDATE''' oder '''DELETE''' Anweisung.{br}
{br}
<code sql>CREATE PROCEDURE addTitle(@title_id VARCHAR(6), @au_id VARCHAR(11),
@title VARCHAR(20), @title_type CHAR(12))
AS
BEGIN TRAN
INSERT titles(title_id, title, type)
VALUES (@title_id, @title, @title_type)
IF (
ERROR <> 0) BEGIN
PRINT 'Unexpected error occurred!'
ROLLBACK TRAN
RETURN 1
END
INSERT titleauthor(au_id, title_id)
VALUES (@au_id, @title_id)
IF (ERROR <> 0) BEGIN
PRINT 'Unexpected error occurred!'
ROLLBACK TRAN
RETURN 1
END
COMMIT TRAN
RETURN 0</code>
{br}
Diese Art der Lösung birgt beträchtige Wiederholung, gerade dann wenn in Ihrer Unternehmenslogik die Implementierung von mehr als zwei Transact-SQL benötigt wird. Eine elegantere Lösung ist es den Code in eine typische Bearbeitungsprozedur zu gruppieren:{br}
{br}
<code sql>CREATE PROCEDURE addTitle(@title_id VARCHAR(6), @au_id VARCHAR(11),
@title VARCHAR(20), @title_type CHAR(12))
AS
BEGIN TRAN
INSERT titles(title_id, title, type)
VALUES (@title_id, @title, @title_type)
IF (
ERROR <> 0) GOTO ERR_HANDLER
INSERT titleauthor(au_id, title_id)
VALUES (@au_id, @title_id)
IF (@@ERROR <> 0) GOTO ERR_HANDLER
COMMIT TRAN
RETURN 0
ERR_HANDLER:
PRINT 'Unexpected error occurred!'
ROLLBACK TRAN
RETURN 1