我写了这个存储过程
ALTER PROCEDURE [dbo].[CERRARVIAJE]
( @ViajeID INT,
@Reloj MONEY,
@Peaje MONEY,
@Equipaje MONEY,
@Adicional MONEY,
@Plus MONEY,
@MontoAutorizado MONEY,
@CerrarEnBase BIT,
@UsuarioCierra INT,
@Motivo Varchar(100),
@Fecha DATETIME
)
AS
BEGIN
SET NOCOUNT ON;
SET XACT_ABORT ON
DECLARE @NuevoEstado INT
DECLARE @DireccionDestino VARCHAR(200)
DECLARE @Punto Geography
DECLARE @movil INT
DECLARE @chofer INT
DECLARE @Cierre VARCHAR(10)
DECLARE @VisualId VARCHAR(10)
IF @Fecha IS NULL
BEGIN
SET @Fecha = GETDATE()
END
IF @ViajeID IS NOT NULL
BEGIN
SELECT @movil = C.MovilID,
@chofer = V.ChoferID ,
@VisualId = V.VisualID,
@DireccionDestino = DireccionDestino,
@Punto = Destino
FROM CHOFERES C (NOLOCK)
INNER JOIN VIAJES V (NOLOCK)
ON C.Id = V.ChoferId
WHERE V.ID = @ViajeID
--Si el usuario que cierra es el chofer, se obtiene su id de usuario
IF @UsuarioCierra = -1
BEGIN
SELECT @UsuarioCierra = Ch.UsuarioID From Viajes V (NOLOCK), Choferes Ch (NOLOCK) Where V.ID = @ViajeID AND Ch.ID = V.ChoferID
END
--Se establece el nuevo estado que tendrá el viaje
IF @CerrarEnBase = 0
BEGIN
SET @NuevoEstado = 13 --Completado
END
ELSE
BEGIN
SET @NuevoEstado = 18 --Cierra Base
END
--El motivo sólo es necesario si el viaje lo cerró la base
IF @CerrarEnBase = 0
BEGIN
SET @Motivo = ''
END
--Si el operador no puso dirección de destino al crear el viaje se busca mediante la tabla Recorridos
IF @DireccionDestino IS NULL
BEGIN
SELECT @DireccionDestino = Direccion,
@Punto = Punto
FROM Recorridos (NOLOCK)
WHERE ViajeID = @ViajeID
AND ID IN (SELECT MAX(ID) MID
FROM Recorridos (NOLOCK)
WHERE ViajeID = @ViajeID)
END
DECLARE @Success BIT
SELECT @Success = 0
WHILE @Success = 0
BEGIN TRY
IF @@TRANCOUNT > 0
BEGIN
SAVE TRANSACTION CERRARVIAJE
END
ELSE
BEGIN
BEGIN TRANSACTION
END
--se actualizan los datos del viaje que se va a cerrar
UPDATE Viajes
SET EstadoID = @NuevoEstado,
FechaCompletado = @Fecha,
CerroUsuarioID = @UsuarioCierra,
MotivoCerrarBase = @Motivo,
Destino = @Punto,
DireccionDestino = @DireccionDestino
WHERE ID = @ViajeID
--se cambia el estado del móvil en calle
UPDATE MOVILESENCALLE SET ESTADO = 1 WHERE ID = @movil
--se guarda el registro en ViajesLog
INSERT INTO [dbo].[ViajesLog]
([Id],[TipoViajeId],[EstadoId],[UsuarioId],[ChoferId],[SubEmpresaId],[PINPasajero],[FechaSolicitado],[FechaUltimoEstado],[FechaAceptado],[FechaPasajeroABordo],[FechaCompletado]
,[FechaCancelado],[FechaCanceladoPasajero],[Origen],[DireccionOrigen],[Destino],[DireccionDestino],[UbicacionActual],[DireccionUbicacionActual],[FlotaIDOriginal],[FechaUniverso]
,[VISUALID],[FechaCreacion],[Observaciones],[Observaciones2],[NoFumador],[AnimalDom],[ServicioVan],[Ticketera],[BaulVacio],[AireAcondicionado],[MotivoCancelacionPasajero],[NumeroViajeCliente]
,[NumeroSiniestro],[TipoMovilId],[CerroUsuarioId],[TienePremio],[Premio],[RequiereVoucher],[MotivoCerrarBase],[EsMensajeria],[FechaObjetivo],[Autorizacion]
,[NombreApellidoPasajero],[CelularPasajero],[ZonaID],[OperadorID],[AutorizacionUsuarioId],[Condicional], [MovilId])
SELECT V.[Id],[TipoViajeId],[EstadoId],V.[UsuarioId],[ChoferId],[SubEmpresaId],[PINPasajero],[FechaSolicitado],[FechaUltimoEstado],[FechaAceptado],[FechaPasajeroABordo],[FechaCompletado]
,[FechaCancelado],[FechaCanceladoPasajero],[Origen],[DireccionOrigen],[Destino],[DireccionDestino],[UbicacionActual],[DireccionUbicacionActual],[FlotaIDOriginal],[FechaUniverso]
,[VISUALID],[FechaCreacion],V.[Observaciones],[Observaciones2],[NoFumador],[AnimalDom],[ServicioVan],[Ticketera],[BaulVacio],[AireAcondicionado],[MotivoCancelacionPasajero],[NumeroViajeCliente]
,[NumeroSiniestro],[TipoMovilId],[CerroUsuarioId],[TienePremio],[Premio],[RequiereVoucher],[MotivoCerrarBase],[EsMensajeria],[FechaObjetivo],[Autorizacion]
,[NombreApellidoPasajero],[CelularPasajero],[ZonaID],[OperadorID],[AutorizacionUsuarioId],[Condicional], C.MovilId
FROM [dbo].[Viajes] V (NOLOCK)
LEFT JOIN Choferes C (NOLOCK)
ON V.ChoferId = C.Id
WHERE V.ID = @ViajeID
--se elimina el registro de la tabla Viajes
DELETE FROM Viajes
WHERE ID = @ViajeID
--se elimina el registro de la tabla MontosViajes
DELETE FROM [dbo].[MontosViajes] WHERE
ViajeID = @ViajeID
--se crea el nuevo registro en la tabla MontosViajes
INSERT INTO [dbo].[MontosViajes] ([ViajeId],[Reloj],[Peaje],[Equipaje],[Adicional],[Plus],[MontoTotal],
[MontoNetoChofer],[MontoTaxiCorp],[MontoFlotaRecibioViaje],[MontoFlotaRealizoViaje],
[FlotaRecibioViajeID],[FlotaRealizoViajeID],[SubEmpresaID])
SELECT TOP 1 @ViajeID,
@Reloj,
@Peaje,
@Equipaje,
@Adicional,
@Plus,
@MontoAutorizado,
@MontoAutorizado * (1 - F.DescuentoPorcentaje / 100.0) - F.DescuentoFijoTotal,
0,
CASE WHEN V.FlotaIdOriginal = SF.FlotaID THEN F.DescuentoFijoTotal
ELSE F.DescuentoFijoPropio
END + @MontoAutorizado * (F.DescuentoPorcentaje / 100.0),
CASE WHEN V.FlotaIdOriginal = SF.FlotaID THEN 0
ELSE F.DescuentoFijoOtraFlota
END,
V.FlotaIdOriginal,
SF.FlotaID,
V.SubEmpresaID
FROM ViajesFull V (NOLOCK)
INNER JOIN Choferes C (NOLOCK)
ON V.ChoferId = C.Id
INNER JOIN Moviles M (NOLOCK)
ON C.MovilId = M.Id
INNER JOIN SubFlotas SF (NOLOCK)
ON M.SubFlotaID = SF.ID
INNER JOIN FLotas F (NOLOCK)
ON V.FlotaIdOriginal = F.ID
WHERE V.ID = @ViajeID
--se establece texto para guardar en el log
IF @CerrarEnBase = 0
BEGIN
SET @Cierre = 'FINAL '
END
ELSE
BEGIN
SET @Cierre = 'A BASE '
END
--se guarda registro en el log de acciones
INSERT INTO AccionesLog (ChoferID, MovilID, ViajeID, UsuarioID, Accion, Stamp)
VALUES (@chofer, @movil, @ViajeID, @UsuarioCierra, 'CERRO VIAJE ' + @Cierre + @VisualId + ' POR ' + CONVERT(VARCHAR, @MontoAutorizado), GETDATE())
lbexit:
IF @@TRANCOUNT = 0
COMMIT TRAN;
SET @Success = 1 -- To exit the loop
END TRY
BEGIN CATCH
DECLARE @ERROR INT, @MESSAGE VARCHAR(4000), @XSTATE INT;
SELECT @ERROR = ERROR_NUMBER(), @MESSAGE = ERROR_MESSAGE(), @XSTATE = XACT_STATE();
--IF @XSTATE = -1
-- ROLLBACK;
IF --@XSTATE = 1 AND
@@TRANCOUNT = 0
ROLLBACK;
IF --@XSTATE = 1 AND
@@TRANCOUNT > 0
ROLLBACK TRANSACTION CERRARVIAJE;
IF @ERROR IN (1204, -- SqlOutOfLocks
1205, -- SqlDeadlockVictim
1222 -- SqlLockRequestTimeout
)
BEGIN
-- This delay is to give the blocking
-- transaction time to finish.
-- So you need to tune according to your
-- environment
WAITFOR DELAY '00:00:02'
END
ELSE
-- If we don't have a handler for current error
-- then we throw an exception and abort the loop
THROW;
END CATCH
END
END
我遇到了这个错误:
EXECUTE之后的事务计数表示BEGIN和COMMIT语句的数量不匹配。先前的计数= 0,当前计数= 1。