Necesito realizar una ACTUALIZACIÓN e INSERTAR en una sola transacción. Ese código funciona bien por sí solo, pero me gustaría poder llamarlo fácilmente y pasar los parámetros requeridos. Cuando intento anidar esta transacción en un procedimiento almacenado, me encuentro con muchos errores de sintaxis.
¿Cómo puedo encapsular el siguiente código para que pueda llamarse fácilmente?
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
Respuestas:
Le gusta la necesidad de ajustar ese código en
CREATE PROCEDURE ...
sintaxis y eliminar lasGO
declaraciones despuésBEGIN TRANSACTION
y antesCOMMIT TRANSACTION
.También tenga en cuenta que he agregado un
TRY...CATCH
bloque de declaración para permitir realizar unaROLLBACK TRANSACTION
declaración en caso de que ocurra algún error. Probablemente necesite un mejor manejo de errores que eso, pero sin conocer sus requisitos, eso es difícil en el mejor de los casos.Algunas buenas lecturas:
Especifique siempre el esquema
Procedimiento almacenado Mejores prácticas
Malos hábitos para evitar
fuente
SAVE TRANS
implicaciones del comando.Si desea manejar adecuadamente los procedimientos almacenados anidados que pueden manejar transacciones (ya sea que se inicie desde T-SQL o el código de la aplicación), debe seguir la plantilla que describí en la siguiente respuesta:
¿Estamos obligados a manejar la transacción en código C # así como en el procedimiento almacenado
Notarás dos diferencias de lo que estás intentando aquí:
El uso de
RAISERROR
dentro delCATCH
bloque. Esto burbujea el error hasta el nivel de llamada (ya sea en la base de datos o en la capa de aplicación), por lo que se puede tomar una decisión con respecto al hecho de que ocurrió un error.No se
SAVE TRANSACTION
. Nunca he encontrado un caso para usar esto. Sé que algunas personas lo prefieren, pero en todo lo que he hecho en cualquier lugar en el que he trabajado, la noción de que ocurra un error dentro de cualquiera de los niveles anidados implica que cualquier trabajo que ya se haya realizado no es válido. Al usarloSAVE TRANSACTION
, solo está volviendo al estado justo antes de que se llame a este Procedimiento almacenado, dejando el proceso existente como válido.Si desea obtener más detalles
SAVE TRANSACTION
, eche un vistazo a la información en esta respuesta:Cómo deshacer cuando se inician 3 procedimientos almacenados desde un procedimiento almacenado
Otro problema con
SAVE TRANSACTION
es un matiz de su comportamiento, como se señala en la página de MSDN para GUARDAR TRANSACCIÓN (énfasis agregado):Es decir, debe tener mucho cuidado de dar a cada Punto de guardado en cada Procedimiento almacenado un nombre único en todos los Puntos de guardado en todos los Procedimientos almacenados. Los siguientes ejemplos ilustran este punto.
Este primer ejemplo muestra lo que sucede cuando reutiliza el nombre del punto de guardado; solo se revierte el punto de guardado del nivel más bajo.
Este segundo ejemplo muestra lo que sucede cuando usa nombres únicos de puntos de guardado; el punto de guardado del nivel deseado se revierte.
fuente