Мне нужно выполнить ОБНОВЛЕНИЕ и ВСТАВКУ в одной транзакции. Этот код прекрасно работает сам по себе, но я хотел бы иметь возможность легко вызывать его и передавать необходимые параметры. Когда я пытаюсь вложить эту транзакцию в хранимую процедуру, я сталкиваюсь с множеством синтаксических ошибок.
Как я могу инкапсулировать следующий код, чтобы его можно было легко вызвать?
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
Ответы:
Вам нужно обернуть этот код в
CREATE PROCEDURE ...
синтаксис и удалитьGO
операторы послеBEGIN TRANSACTION
и доCOMMIT TRANSACTION
.Также обратите внимание, что я добавил
TRY...CATCH
блок операторов, чтобы разрешить выполнениеROLLBACK TRANSACTION
оператора в случае возникновения ошибки. Возможно, вам нужна лучшая обработка ошибок, но без знания ваших требований это в лучшем случае сложно.Некоторое хорошее чтение:
Всегда указывайте схему
Хранимая процедура Best Practices
Вредных привычек, которых следует избегать
источник
SAVE TRANS
последствиях команды.Если вы хотите правильно обрабатывать вложенные хранимые процедуры, которые могут обрабатывать транзакции (независимо от того, были ли они запущены из T-SQL или из кода приложения), вы должны следовать шаблону, который я описал в следующем ответе:
Должны ли мы обрабатывать транзакции в коде C #, а также в хранимых процедурах
Вы заметите два отличия от того, что вы пытаетесь здесь:
Использование
RAISERROR
внутриCATCH
блока. Это приводит к возникновению ошибки до уровня вызова (будь то на уровне БД или на уровне приложения), поэтому можно принять решение относительно того, что произошла ошибка.Нет
SAVE TRANSACTION
. Я никогда не нашел случая использовать это. Я знаю, что некоторые люди предпочитают это, но во всем, что я когда-либо делал в любом месте, где я работал, понятие ошибки, возникающей на любом из вложенных уровней, подразумевало, что любая работа, которая уже была сделана, была недействительной. При использованииSAVE TRANSACTION
вы возвращаетесь в состояние только перед вызовом этой хранимой процедуры, в результате чего существующий процесс остается действительным.Если вы хотите получить более подробную информацию
SAVE TRANSACTION
, ознакомьтесь с информацией в этом ответе:Как выполнить откат при запуске 3 хранимых процедур из одной хранимой процедуры
Другая проблема, с
SAVE TRANSACTION
которой он сталкивается - это нюанс его поведения, как отмечено на странице MSDN для SAVE TRANSACTION (выделение добавлено):Это означает, что вы должны быть очень осторожны, чтобы дать каждой точке сохранения в каждой хранимой процедуре имя, уникальное для всех точек сохранения во всех хранимых процедурах. Следующие примеры иллюстрируют эту точку зрения.
Этот первый пример показывает, что происходит при повторном использовании имени точки сохранения; откатывается только точка сохранения самого низкого уровня.
Этот второй пример показывает, что происходит, когда вы используете уникальные имена точек сохранения; Точка сохранения нужного уровня откатывается.
источник