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 = null
Insert 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 OUT
IF @Error IS NOT NULL BEGIN
IF @@TRANCOUNT > 0
ROLLBACK 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 @DetalleVentaType
OPEN CursorDetalleVenta
FETCH NEXT FROM CursorDetalleVenta INTO @IdProducto, @Cantidad, @Descuento, @Importe, @MetodoEntrega
WHILE @@FETCH_STATUS = 0 BEGIN
EXEC Registrar_Detalle_Venta
@NumeroRemision = @NumeroRemision,
@IdProducto = @IdProducto,
@Cantidad = @Cantidad,
@Descuento = @Descuento,
@Importe = @Importe,
@MetodoEntrega = @MetodoEntrega,
@SelectFinal = 0,
@Error = @Error OUT
IF @Error IS NOT NULL BEGIN
IF @@TRANCOUNT > 0
ROLLBACK 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 > 0
ROLLBACK 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 NULL
SELECT @Error Error
IF @@TRANCOUNT > 0
ROLLBACK 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)
) BEGIN
SET @Error = 'No se ingresaron todos los productos que son requeridos para este producto.'
IF @SelectFinal = 1 OR @SelectFinal IS NULL
SELECT @Error Error
IF @@TRANCOUNT > 0
ROLLBACK 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 @TablaDetalleProduccion
OPEN CursorDetalleProduccion
FETCH NEXT FROM CursorDetalleProduccion INTO @IdProducto, @IdMateriaPrima, @CantidadMPUsada
WHILE @@FETCH_STATUS = 0 BEGIN
Insert 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 OUTPUT
IF @Error IS NOT null BEGIN
IF @@TRANCOUNT > 0
ROLLBACK TRAN
SET @Error = 'Agrega_Movimiento_Inventario: ' + @Error
IF @SelectFinal = 1 OR @SelectFinal IS NULL
SELECT @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 OUT
IF @Error IS NOT NULL BEGIN
IF @@TRANCOUNT > 0
ROLLBACK TRAN
SET @Error = 'Agrega_Movimiento_Inventario: ' + @Error
IF @SelectFinal = 1 OR @SelectFinal IS NULL
SELECT @Error Error
RETURN
END
COMMIT TRAN
SET @Error = (SELECT ERROR_PROCEDURE() + ' ' + ERROR_MESSAGE())
IF @SelectFinal = 1 OR @SelectFinal IS NULL
SELECT @Error Error
END TRY
BEGIN CATCH
IF @@TRANCOUNT > 0
ROLLBACK TRAN
SET @Error = (SELECT ERROR_PROCEDURE() + ' ' + ERROR_MESSAGE())
IF @SelectFinal = 1 OR @SelectFinal IS NULL
SELECT @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 NULL
SELECT @Error Error
END TRY
BEGIN CATCH
SET @Error = ERROR_PROCEDURE() + ' ' + ERROR_MESSAGE()
IF @SelectFinal = 1 OR @SelectFinal IS NULL
SELECT @Error Error
END CATCH
END
Valora esta pregunta


0