Ich muss ein UPDATE und ein INSERT in einer einzigen Transaktion ausführen. Dieser Code funktioniert von sich aus einwandfrei, aber ich möchte ihn einfach aufrufen und die erforderlichen Parameter übergeben können. Wenn ich versuche, diese Transaktion in einer gespeicherten Prozedur zu verschachteln, treten viele Syntaxfehler auf.
Wie kann ich den folgenden Code kapseln, damit er einfach aufgerufen werden kann?
BEGIN TRANSACTION AssignUserToTicket
GO
DECLARE @updateAuthor varchar(100)
DECLARE @assignedUser varchar(100)
DECLARE @ticketID bigint
SET @updateAuthor = 'user1'
SET @assignedUser = 'user2'
SET @ticketID = 123456
UPDATE tblTicket SET ticketAssignedUserSamAccountName = @assignedUser WHERE (ticketID = @ticketID);
INSERT INTO [dbo].[tblTicketUpdate]
([ticketID]
,[updateDetail]
,[updateDateTime]
,[userSamAccountName]
,[activity])
VALUES
(@ticketID,
'Assigned ticket to ' + @assignedUser,
GetDate(),
@updateAuthor,
'Assign');
GO
COMMIT TRANSACTION AssignUserToTicket
sql-server
sql-server-2012
t-sql
stored-procedures
transaction
Charlie K.
quelle
quelle
Antworten:
Sie möchten diesen Code in
CREATE PROCEDURE ...
Syntax einschließen und dieGO
Anweisungen nachBEGIN TRANSACTION
und vor entfernenCOMMIT TRANSACTION
.Beachten Sie auch, dass ich einen
TRY...CATCH
Anweisungsblock hinzugefügt habe , um das Ausführen einerROLLBACK TRANSACTION
Anweisung für den Fall eines Fehlers zu ermöglichen . Sie benötigen wahrscheinlich eine bessere Fehlerbehandlung, aber ohne Kenntnis Ihrer Anforderungen ist dies bestenfalls schwierig.Einige gute Lektüre:
Geben Sie immer das Schema an
Best Practices für gespeicherte Verfahren
Schlechte Gewohnheiten zu vermeiden
quelle
SAVE TRANS
Auswirkungen des Befehls nicht bewusst .Wenn Sie verschachtelte gespeicherte Prozeduren, die Transaktionen verarbeiten können (unabhängig davon, ob sie mit T-SQL oder App-Code gestartet wurden), ordnungsgemäß verarbeiten möchten, sollten Sie der Vorlage folgen, die ich in der folgenden Antwort beschrieben habe:
Müssen wir Transaktionen sowohl im C # -Code als auch in gespeicherten Prozeduren abwickeln?
Sie werden dort zwei Unterschiede zu dem bemerken, was Sie hier versuchen:
Die Verwendung
RAISERROR
innerhalb desCATCH
Blocks. Dadurch wird der Fehler auf die aufrufende Ebene (ob in der DB- oder App-Ebene) übertragen, sodass eine Entscheidung darüber getroffen werden kann, ob ein Fehler aufgetreten ist.Nein
SAVE TRANSACTION
. Ich habe nie einen Grund dafür gefunden. Ich weiß, dass einige Leute es vorziehen, aber bei allem, was ich jemals an einem Ort getan habe, an dem ich gearbeitet habe, implizierte die Vorstellung eines Fehlers, der in einer der verschachtelten Ebenen auftrat, dass die bereits geleistete Arbeit ungültig war. Durch die VerwendungSAVE TRANSACTION
kehren Sie erst in den Status zurück, bevor diese gespeicherte Prozedur aufgerufen wurde, und belassen den vorhandenen Prozess als anderweitig gültig.Wenn Sie weitere Informationen zu wünschen
SAVE TRANSACTION
, lesen Sie bitte die Informationen in dieser Antwort:Zurücksetzen, wenn 3 gespeicherte Prozeduren von einer gespeicherten Prozedur gestartet werden
Ein weiteres Problem
SAVE TRANSACTION
ist eine Nuance des Verhaltens, wie auf der MSDN-Seite für SAVE TRANSACTION (Hervorhebung hinzugefügt) angegeben:Das heißt, Sie müssen sehr vorsichtig sein, um jedem Speicherpunkt in jeder gespeicherten Prozedur einen Namen zu geben, der für alle Speicherpunkte in allen gespeicherten Prozeduren eindeutig ist. Die folgenden Beispiele veranschaulichen diesen Punkt.
Dieses erste Beispiel zeigt, was passiert, wenn Sie den Namen des Speicherpunkts wiederverwenden. Nur der Speicherpunkt der niedrigsten Ebene wird zurückgesetzt.
Dieses zweite Beispiel zeigt, was passiert, wenn Sie eindeutige Speicherpunktnamen verwenden. Der Speicherpunkt des gewünschten Levels wird zurückgesetzt.
quelle