StoredProcedure con transacciones anidadas a veces se ejecute correctamente y a veces no
Publicado por Manuel Alejandro (4 intervenciones) el 27/03/2020 16:50:36
¡Hola!
Me encuentro realizando un procedure para registrar ventas. Se pueden realizar ventas por productos que se encuentran en inventario o por productos que se producen al momento de realizar la venta. Me encuentro realizando pruebas con productos que requieren registrar una producción (Entra al procedure Registrar_Produccion) y posteriormente al procedure Registrar_Detalle_Venta.
El problema es que al ejecutarlo devuelve este error "Registrar_Produccion Transaction count after EXECUTE indicates a mismatching number of BEGIN and COMMIT statements. Previous count = 1, current count = 0." Se que va relacionado con la cantidad COMMITS y ROLLBACK dentro del procedure ya que antes me había sucedido algo similar y era porque me faltaba agregar ROLLBACK pero esta vez no puedo detectar que es lo que lo ocasiona.
Vuelvo a recalcarlo, este error lo devuelve el procedure Registrar_Venta, el cual ejecuta los procedures Registrar_Produccion y Registrar_Detalle_Venta.
P.D. Estoy probando este procedure en una base de datos alojada en el mismo ordenador en donde realizo las pruebas. Cuando recién enciendo la computadora el procedure se ejecuta correctamente. Pero quiero intentar ejecutarlo nuevamente es que sucede este error.
Me encuentro realizando un procedure para registrar ventas. Se pueden realizar ventas por productos que se encuentran en inventario o por productos que se producen al momento de realizar la venta. Me encuentro realizando pruebas con productos que requieren registrar una producción (Entra al procedure Registrar_Produccion) y posteriormente al procedure Registrar_Detalle_Venta.
El problema es que al ejecutarlo devuelve este error "Registrar_Produccion Transaction count after EXECUTE indicates a mismatching number of BEGIN and COMMIT statements. Previous count = 1, current count = 0." Se que va relacionado con la cantidad COMMITS y ROLLBACK dentro del procedure ya que antes me había sucedido algo similar y era porque me faltaba agregar ROLLBACK pero esta vez no puedo detectar que es lo que lo ocasiona.
Vuelvo a recalcarlo, este error lo devuelve el procedure Registrar_Venta, el cual ejecuta los procedures Registrar_Produccion y Registrar_Detalle_Venta.
P.D. Estoy probando este procedure en una base de datos alojada en el mismo ordenador en donde realizo las pruebas. Cuando recién enciendo la computadora el procedure se ejecuta correctamente. Pero quiero intentar ejecutarlo nuevamente es que sucede este error.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
CREATE PROCEDURE Registrar_Venta
@IdCliente int,@MetodoPago varchar (18),
@IdSucursal tinyint,@IdPersonal int,@DetalleVentaType DetalleVentaType READONLY,@TablaDetalleProduccion DetalleProduccionType READONLY,@Tiro varchar(10) = null,
@Obra varchar(100)
AS
BEGIN
BEGIN TRY
BEGIN TRAN
DECLARE @NumeroRemision int
SET @NumeroRemision = (Select ISNULL(MAX(NumeroRemision),0)+1 from Venta)
DECLARE @Error varchar(200)
SET @Error = nullInsert into Venta (NumeroRemision,IdCliente, FechaVenta, MetodoPago, IdSucursal, IdPersonal, Cancelada)
values (@NumeroRemision, @IdCliente, GETDATE(), @MetodoPago, @IdSucursal, @IdPersonal, 0)
-------------------------Se registra la produccion si es que hay----------------------------
IF (Select COUNT(IdProducto) from @TablaDetalleProduccion) > 0 BEGIN
DECLARE @IdUsuario int
SET @IdUsuario = (Select TOP 1 IdUsuario from Usuario WHERE IdPersonal = @IdPersonal)
DECLARE @CantidadProducida decimal(16,2)
SET @CantidadProducida = (Select Cantidad from @DetalleVentaType)
EXEC Registrar_Produccion
@TablaDetalleProduccion = @TablaDetalleProduccion,
@CantidadProducida = @CantidadProducida,
@IdCliente = @IdCliente,
@IdSucursal = @IdSucursal,
@Tiro = @Tiro,
@Obra = @Obra,
@IdUsuario = @IdUsuario,
@SelectFinal = 0,
@Error = @Error OUTIF @Error IS NOT NULL BEGIN
IF @@TRANCOUNT > 0ROLLBACK TRAN
Select @Error Error
RETURN
END
END
------------------------------------------------------------------------------
--------------------------Se registra el detalle de la venta-----------------------------------------
DECLARE @IdProducto int
DECLARE @Cantidad decimal(16,2)
DECLARE @Descuento decimal(5,2)
DECLARE @Importe decimal(16,2)
DECLARE @MetodoEntrega varchar(60)
DECLARE CursorDetalleVenta CURSOR LOCAL STATIC READ_ONLY FORWARD_ONLY
FOR SELECT * from @DetalleVentaTypeOPEN CursorDetalleVenta
FETCH NEXT FROM CursorDetalleVenta INTO @IdProducto, @Cantidad, @Descuento, @Importe, @MetodoEntrega
WHILE @@FETCH_STATUS = 0 BEGINEXEC Registrar_Detalle_Venta
@NumeroRemision = @NumeroRemision,
@IdProducto = @IdProducto,
@Cantidad = @Cantidad,
@Descuento = @Descuento,
@Importe = @Importe,
@MetodoEntrega = @MetodoEntrega,
@SelectFinal = 0,
@Error = @Error OUTIF @Error IS NOT NULL BEGIN
IF @@TRANCOUNT > 0ROLLBACK TRAN
SELECT @Error Error
RETURN
END
FETCH NEXT FROM CursorDetalleVenta INTO @IdProducto, @Cantidad, @Descuento, @Importe, @MetodoEntrega
END
----------------------------------------------------------------------------------------------------------
COMMIT TRAN
SELECT ERROR_PROCEDURE() + ' ' + ERROR_MESSAGE() Error, @NumeroRemision NumeroRemision
END TRY
BEGIN CATCH
IF @@TRANCOUNT > 0ROLLBACK TRAN
SELECT ERROR_PROCEDURE() + ' ' + ERROR_MESSAGE() Error
END CATCH
END
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
CREATE PROCEDURE Registrar_Produccion
@TablaDetalleProduccion DetalleProduccionType READONLY,@CantidadProducida decimal(16,2),
@IdCliente int,@IdSucursal tinyint,@Tiro varchar(10),
@Obra varchar(100),
@IdUsuario int,@SelectFinal bit = null,
@Error varchar(200) OUT
AS
BEGIN
BEGIN TRY
BEGIN TRAN
IF(Select COUNT(*) from @TablaDetalleProduccion) = 0 BEGIN
SET @Error = 'No se ingresó la materia prima utilizada para la producción'
IF @SelectFinal = 1 OR @SelectFinal IS NULLSELECT @Error Error
IF @@TRANCOUNT > 0ROLLBACK TRAN
RETURN
END
DECLARE @IdProductoAProducir int
SET @IdProductoAProducir = (Select TOP 1 IdProducto from @TablaDetalleProduccion)
IF (Select COUNT(IdMateriaPrima) from Producto_MateriaPrima WHERE IdProducto = @IdProductoAProducir AND Requerido = 1)
<> (Select COUNT(IdMateriaPrima) from @TablaDetalleProduccion
WHERE IdMateriaPrima IN
(Select IdMateriaPrima from Producto_MateriaPrima WHERE IdProducto = @IdProductoAProducir AND Requerido = 1)
) BEGINSET @Error = 'No se ingresaron todos los productos que son requeridos para este producto.'
IF @SelectFinal = 1 OR @SelectFinal IS NULLSELECT @Error Error
IF @@TRANCOUNT > 0ROLLBACK TRAN
RETURN
END
DECLARE @IdProduccion int
SET @IdProduccion = (Select ISNULL(MAX(IdProduccion),0)+1 from Produccion)
INSERT INTO Produccion (IdProduccion, CantidadProducida, IdCliente, Fecha, IdSucursal, Tiro, Obra)
values (@IdProduccion, @CantidadProducida, @IdCliente, GETDATE(), @IdSucursal, @Tiro, @Obra)
DECLARE @IdProducto int
DECLARE @IdMateriaPrima int
DECLARE @CantidadMPUsada decimal(16,2)
DECLARE CursorDetalleProduccion CURSOR LOCAL STATIC READ_ONLY FORWARD_ONLY
FOR SELECT * from @TablaDetalleProduccionOPEN CursorDetalleProduccion
FETCH NEXT FROM CursorDetalleProduccion INTO @IdProducto, @IdMateriaPrima, @CantidadMPUsada
WHILE @@FETCH_STATUS = 0 BEGINInsert into Detalle_Produccion (IdProduccion, IdProducto, IdMateriaPrima, CantidadMPUsada)
values (@IdProduccion, @IdProducto, @IdMateriaPrima, @CantidadMPUsada)
EXEC Agrega_Movimiento_Inventario
@TipoMovimiento = 'Salida por produccion',
@IdProduccion = @IdProduccion,
@IdProducto = @IdMateriaPrima,
@IdSucursal = @IdSucursal,
@Cantidad = @CantidadMPUsada,
@SelectFinal = 0,
@IdUsuario = @IdUsuario,
@Error = @Error OUTPUTIF @Error IS NOT null BEGIN
IF @@TRANCOUNT > 0ROLLBACK TRAN
SET @Error = 'Agrega_Movimiento_Inventario: ' + @Error
IF @SelectFinal = 1 OR @SelectFinal IS NULLSELECT @Error Error
RETURN
END
FETCH NEXT FROM CursorDetalleProduccion INTO @IdProducto, @IdMateriaPrima, @CantidadMPUsada
END
SET @IdProducto = (Select DISTINCT (IdProducto) from @TablaDetalleProduccion)
EXEC Agrega_Movimiento_Inventario
@TipoMovimiento = 'Entrada por produccion',
@IdProduccion = @IdProduccion,
@IdProducto = @IdProducto,
@IdSucursal = @IdSucursal,
@Cantidad = @CantidadProducida,
@SelectFinal = 0,
@IdUsuario = @IdUsuario,
@Error = @Error OUTIF @Error IS NOT NULL BEGIN
IF @@TRANCOUNT > 0ROLLBACK TRAN
SET @Error = 'Agrega_Movimiento_Inventario: ' + @Error
IF @SelectFinal = 1 OR @SelectFinal IS NULLSELECT @Error Error
RETURN
END
COMMIT TRAN
SET @Error = (SELECT ERROR_PROCEDURE() + ' ' + ERROR_MESSAGE())
IF @SelectFinal = 1 OR @SelectFinal IS NULLSELECT @Error Error
END TRY
BEGIN CATCH
IF @@TRANCOUNT > 0ROLLBACK TRAN
SET @Error = (SELECT ERROR_PROCEDURE() + ' ' + ERROR_MESSAGE())
IF @SelectFinal = 1 OR @SelectFinal IS NULLSELECT @Error Error
END CATCH
END
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
CREATE PROCEDURE Registrar_Detalle_Venta
@NumeroRemision int,@IdProducto int,@Cantidad decimal (16,2),
@Descuento decimal (5,2),
@Importe decimal (16,2),
@MetodoEntrega varchar (60),
@SelectFinal bit = null,
@Error varchar(200) OUT
AS
BEGIN
BEGIN TRY
Insert into Detalle_Venta values (@NumeroRemision, @IdProducto, @Cantidad, @Descuento, @Importe, @MetodoEntrega)
SET @Error = ERROR_PROCEDURE() + ' ' + ERROR_MESSAGE()
IF @SelectFinal = 1 OR @SelectFinal IS NULLSELECT @Error Error
END TRY
BEGIN CATCH
SET @Error = ERROR_PROCEDURE() + ' ' + ERROR_MESSAGE()
IF @SelectFinal = 1 OR @SelectFinal IS NULLSELECT @Error Error
END CATCH
END
Valora esta pregunta


0
