Muszę wykonać AKTUALIZACJĘ i WSTAW w jednej transakcji. Ten kod działa dobrze sam, ale chciałbym móc go łatwo wywoływać i przekazywać wymagane parametry. Kiedy próbuję zagnieździć tę transakcję w procedurze składowanej, napotykam wiele błędów składniowych.
Jak mogę obudować poniższy kod, aby można go było łatwo wywołać?
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.
źródło
źródło
Odpowiedzi:
Chcesz owinąć ten kod w
CREATE PROCEDURE ...
składnię i usunąćGO
instrukcjeBEGIN TRANSACTION
przed i poCOMMIT TRANSACTION
.Uwaga: dodałem
TRY...CATCH
blok instrukcji, aby umożliwić wykonanieROLLBACK TRANSACTION
instrukcji w przypadku wystąpienia błędu. Prawdopodobnie potrzebujesz lepszej obsługi błędów niż to, ale bez znajomości swoich wymagań jest to w najlepszym razie trudne.Dobra lektura:
Zawsze określaj schemat
Procedury składowane Najlepsze praktyki
Złe nawyki, których należy unikać
źródło
SAVE TRANS
konsekwencji polecenia.Jeśli chcesz poprawnie obsługiwać zagnieżdżone procedury składowane, które mogą obsługiwać transakcje (niezależnie od tego, czy zostały uruchomione z T-SQL lub kodu aplikacji), powinieneś postępować zgodnie z szablonem, który opisałem w następującej odpowiedzi:
Czy jesteśmy zobowiązani do obsługi transakcji w kodzie C #, a także w procedurze przechowywanej
Zauważysz tam dwie różnice w stosunku do tego, co tutaj próbujesz:
Zastosowanie
RAISERROR
wCATCH
bloku. Spowoduje to przeniesienie błędu do poziomu wywołania (zarówno w warstwie bazy danych, jak i aplikacji), dzięki czemu można podjąć decyzję dotyczącą wystąpienia błędu.Nie
SAVE TRANSACTION
. Nigdy nie znalazłem powodu do tego. Wiem, że niektórzy ludzie wolą to, ale we wszystkim, co kiedykolwiek zrobiłem w dowolnym miejscu, w którym pracowałem, pojęcie błędu występującego na dowolnym z zagnieżdżonych poziomów sugerowało, że wszystko, co zostało już wykonane, było nieprawidłowe. Korzystając z tej opcjiSAVE TRANSACTION
, powracasz do stanu tuż przed wywołaniem tej procedury składowanej, pozostawiając istniejący proces jako inny ważny.Jeśli chcesz uzyskać więcej informacji
SAVE TRANSACTION
, zapoznaj się z informacjami w tej odpowiedzi:Jak wycofać, gdy 3 procedury przechowywane są uruchamiane z jednej procedury przechowywanej
Kolejny problem z
SAVE TRANSACTION
jest niuans jego zachowania, jak zauważono na stronie MSDN SAVE TRANSACTION (wyróżnienie dodane):Oznacza to, że należy bardzo uważać, aby nadać każdemu Punktowi zapisu w każdej Procedurze składowanej unikalną nazwę we wszystkich Punktach zapisu we wszystkich Procedurach przechowywanych. Poniższe przykłady ilustrują ten punkt.
Ten pierwszy przykład pokazuje, co się stanie, gdy użyjesz ponownie nazwy punktu zapisu; wycofany zostanie tylko punkt zapisu najniższego poziomu.
Ten drugi przykład pokazuje, co dzieje się, gdy używasz unikatowych nazw punktów zapisu; Punkt zapisu żądanego poziomu jest wycofywany.
źródło