Rollback transacciones

13/09/2004 - 22:21 por fco | Informe spam
en el siguiente proc. almacenado:

begin tran

update tabla1 set campo1= 1
update tabla2 set campo1= 1

IF @@ERROR <> 0
ROLLBACK
ELSE
commit

se supone que si una instruccion falla @error es distinto
de 0, entonces deshace la transaccion con rollback, pero
en lugar de eso se ejecuta la instruccion que no falla y
ademas no confirma la transaccion y me arroja el siguiente
error:

"El recuento de transacciones después de EXECUTE indica
que falta una instrucción COMMIT o ROLLBACK TRANSACTION.
Recuento anterior = 1, recuento actual = 2."

¿alguien sabe como confirmar o deshacer las transacciones,
porque este ejemplo lo saque de la ayuda y no ma habia
dado cuenta que no funciona?

instrucciones obviamente la deshace, pero si esta despues
del if @error ... no lo reconoce..

Preguntas similare

Leer las respuestas

#6 fco
14/09/2004 - 01:40 | Informe spam
Gracias a los que respondieron.

La solucion a este problema es que siempre estuvo
correcto... trabajo hace años con esta instruccion para
deshacer transacciones, creo que debe ser el sueño, ademas
a quien no le ha pasado algo así.

El problema esta cuando quieres actualizar o seleccionar
algo de una tabla que no existe
"update tabla_que_no_existe set campo1= 1"
entonces, en ese caso la transaccion no queda confirmada,
pero si introducimos un valor numerico por ejemplo en un
campo caracter se va a generar el error y entonces deshace
todas las operaciones.

Estuve leyendo sus respuestas y gracias, pero creo que lo
que yo coloco al final de todas las instruciones es lo
mejor. Si se dan cuenta yo sólo coloco una vez al final el
IF @@ERROR <> 0
ROLLBACK
ELSE
commit
..entonces no tenemos que colocarlo despues de cada
ejecucion.
instruccion es correcta, si dio un error en una sentencia
y si las demas estan correctas, se quedara con el valor
que genero el error.

¿En que estaba pensando, si esta instruccón como mencioné
la saque de la ayuda o de un libro de SQL SERVER (ya no me
acuerdo )? Obvio que tenía que estar correcta la
instruccion.



en el siguiente proc. almacenado:

begin tran

update tabla1 set campo1= 1
update tabla2 set campo1= 1

IF @@ERROR <> 0
ROLLBACK
ELSE
commit

se supone que si una instruccion falla @error es distinto
de 0, entonces deshace la transaccion con rollback, pero
en lugar de eso se ejecuta la instruccion que no falla y
ademas no confirma la transaccion y me arroja el


siguiente
error:

"El recuento de transacciones después de EXECUTE indica
que falta una instrucción COMMIT o ROLLBACK TRANSACTION.
Recuento anterior = 1, recuento actual = 2."

¿alguien sabe como confirmar o deshacer las


transacciones,
porque este ejemplo lo saque de la ayuda y no ma habia
dado cuenta que no funciona?

instrucciones obviamente la deshace, pero si esta despues
del if @error ... no lo reconoce..



.

Respuesta Responder a este mensaje
#7 MAXI
14/09/2004 - 01:55 | Informe spam
hola ojo porque no es asi lo que dices

Lee esto:

@@ERROR
Devuelve el número de error de la última instrucción Transact-SQL ejecutada.

Sintaxis
@@ERROR

Tipos devueltos
integer

Observaciones
Cuando Microsoft® SQL ServerT completa con éxito la ejecución de una
instrucción Transact-SQL, en @@ERROR se establece el valor 0. Si se produce
un error, se devuelve un mensaje de error. @@ERROR devuelve el número del
mensaje de error, hasta que se ejecute otra instrucción Transact-SQL. Puede
ver el texto asociado a un número de error @@ERROR en la tabla de sistema
sysmessages.

Al restablecerse @@ERROR con cada instrucción ejecutada, debe comprobarlo
inmediatamente después de la instrucción que desea validar o guardarlo en
una variable local para examinarlo posteriormente.

Ejemplos
A. Utilizar @@ERROR para detectar un error específico
En este ejemplo se utiliza @@ERROR para comprobar si se infringe una
restricción CHECK (error nº 547) en una instrucción UPDATE.

USE pubs
GO
UPDATE authors SET au_id = '172 32 1176'
WHERE au_id = "172-32-1176"

IF @@ERROR = 547
print "A check constraint violation occurred"
B. Utilizar @@ERROR para salir condicionalmente de un procedimiento
La instrucción IF...ELSE de este ejemplo comprueba @@ERROR después de una
instrucción INSERT de un procedimiento almacenado. El valor de la variable
@@ERROR determina el código de retorno enviado al programa que llamó, lo que
indica el éxito o el fracaso del procedimiento.

USE pubs
GO

CREATE PROCEDURE add_author
@au_id varchar(11),@au_lname varchar(40),
@au_fname varchar(20),@phone char(12),
@address varchar(40) = NULL,@city varchar(20) = NULL,
@state char(2) = NULL,@zip char(5) = NULL,
@contract bit = NULL
AS

INSERT INTO authors
(au_id, au_lname, au_fname, phone, address,
city, state, zip, contract) values
(@au_id,@au_lname,@au_fname,@phone,@address,
@city,@state,@zip,@contract)

IF @@ERROR <> 0
BEGIN
PRINT "An error occurred loading the new author information"
RETURN(99)
END
ELSE
BEGIN
PRINT "The new author information has been loaded"
RETURN(0)
END
GO
C. Utilizar @@ERROR para comprobar el éxito de varias instrucciones
Este ejemplo depende de la ejecución con éxito de las instrucciones INSERT y
DELETE. Se establece el valor de @@ERROR en variables locales después de
ambas instrucciones y se utilizan las variables en una rutina de tratamiento
de errores común para la operación.

USE pubs
GO
DECLARE @del_error int, @ins_error int
BEGIN TRAN

DELETE authors
WHERE au_id = '409-56-7088'

SELECT @del_error = @@ERROR

INSERT authors
VALUES('409-56-7008', 'Bennet', 'Abraham', '415 658-9932',
'6223 Bateman St.', 'Berkeley', 'CA', '94705', 1)
SELECT @ins_error = @@ERROR

IF @del_error = 0 AND @ins_error = 0
BEGIN
PRINT "The author information has been replaced"
COMMIT TRAN
END
ELSE
BEGIN
IF @del_error <> 0
PRINT "An error occurred during execution of the DELETE
statement."

IF @ins_error <> 0
PRINT "An error occurred during execution of the INSERT
statement."

ROLLBACK TRAN
END
GO
D. Utilizar @@ERROR con @@ROWCOUNT
Este ejemplo utiliza @@ERROR con @@ROWCOUNT para validar la operación de una
instrucción UPDATE. Se comprueba el valor de @@ERROR para ver si hay un
error y se utiliza @@ROWCOUNT para asegurar que la actualización se aplica
correctamente a una fila de la tabla.

USE pubs
GO
CREATE PROCEDURE change_publisher
@title_id tid,
@new_pub_id char(4)
AS

DECLARE @error_var int, @rowcount_var int

UPDATE titles SET pub_id = @new_pub_id
WHERE title_id = @title_id

SELECT @error_var = @@ERROR, @rowcount_var = @@ROWCOUNT

IF @error_var <> 0
BEGIN
IF @error_var = 547
BEGIN
PRINT "ERROR: Invalid ID specified for new publisher"
RETURN(1)
END
ELSE
BEGIN
PRINT "ERROR: Unhandled error occurred"
RETURN(2)
END
END

IF @rowcount_var = 0
BEGIN
PRINT "Warning: The title_id specified is not valid"
RETURN(1)
END
ELSE
BEGIN
PRINT "The book has been updated with the new publisher"
RETURN(0)
END
GO




Maxi

Buenos Aires - Argentina
Desarrollador .NET 3 Estrellas
Microsoft User Group (MUG)
Mail: Maxi_accotto[arroba]speedy.com.ar
Msn Messager:

"fco" escribió en el mensaje
news:185e01c499eb$1ee33eb0$
Gracias a los que respondieron.

La solucion a este problema es que siempre estuvo
correcto... trabajo hace años con esta instruccion para
deshacer transacciones, creo que debe ser el sueño, ademas
a quien no le ha pasado algo así.

El problema esta cuando quieres actualizar o seleccionar
algo de una tabla que no existe
"update tabla_que_no_existe set campo1= 1"
entonces, en ese caso la transaccion no queda confirmada,
pero si introducimos un valor numerico por ejemplo en un
campo caracter se va a generar el error y entonces deshace
todas las operaciones.

Estuve leyendo sus respuestas y gracias, pero creo que lo
que yo coloco al final de todas las instruciones es lo
mejor. Si se dan cuenta yo sólo coloco una vez al final el
IF @@ERROR <> 0
ROLLBACK
ELSE
commit
..entonces no tenemos que colocarlo despues de cada
ejecucion.
instruccion es correcta, si dio un error en una sentencia
y si las demas estan correctas, se quedara con el valor
que genero el error.

¿En que estaba pensando, si esta instruccón como mencioné
la saque de la ayuda o de un libro de SQL SERVER (ya no me
acuerdo )? Obvio que tenía que estar correcta la
instruccion.



en el siguiente proc. almacenado:

begin tran

update tabla1 set campo1= 1
update tabla2 set campo1= 1

IF @@ERROR <> 0
ROLLBACK
ELSE
commit

se supone que si una instruccion falla @error es distinto
de 0, entonces deshace la transaccion con rollback, pero
en lugar de eso se ejecuta la instruccion que no falla y
ademas no confirma la transaccion y me arroja el


siguiente
error:

"El recuento de transacciones después de EXECUTE indica
que falta una instrucción COMMIT o ROLLBACK TRANSACTION.
Recuento anterior = 1, recuento actual = 2."

¿alguien sabe como confirmar o deshacer las


transacciones,
porque este ejemplo lo saque de la ayuda y no ma habia
dado cuenta que no funciona?

instrucciones obviamente la deshace, pero si esta despues
del if @error ... no lo reconoce..



.

Respuesta Responder a este mensaje
#8 fco
14/09/2004 - 03:34 | Informe spam
ok, tienes razon.
Hasta, me di cuenta que ni siquiera es necesario colocar
esa instruccion, porque con sólo colocar
"Begin tran"
el sql server es el que se encarga de confirmarlas o
deshacerlas si se produce un error, si esta configurado
para confirmar las transacciones automaticamente (que en
la instalacion viene por defecto), o sea no es necesario
colocar commit o rollback ... Excepto si son transacciones
anidadas.


hola ojo porque no es asi lo que dices

Lee esto:

@@ERROR
Devuelve el número de error de la última instrucción


Transact-SQL ejecutada.

Sintaxis
@@ERROR

Tipos devueltos
integer

Observaciones
Cuando Microsoft® SQL ServerT completa con éxito la


ejecución de una
instrucción Transact-SQL, en @@ERROR se establece el


valor 0. Si se produce
un error, se devuelve un mensaje de error. @@ERROR


devuelve el número del
mensaje de error, hasta que se ejecute otra instrucción


Transact-SQL. Puede
ver el texto asociado a un número de error @@ERROR en la


tabla de sistema
sysmessages.

Al restablecerse @@ERROR con cada instrucción ejecutada,


debe comprobarlo
inmediatamente después de la instrucción que desea


validar o guardarlo en
una variable local para examinarlo posteriormente.

Ejemplos
A. Utilizar @@ERROR para detectar un error específico
En este ejemplo se utiliza @@ERROR para comprobar si se


infringe una
restricción CHECK (error nº 547) en una instrucción


UPDATE.

USE pubs
GO
UPDATE authors SET au_id = '172 32 1176'
WHERE au_id = "172-32-1176"

IF @@ERROR = 547
print "A check constraint violation occurred"
B. Utilizar @@ERROR para salir condicionalmente de un


procedimiento
La instrucción IF...ELSE de este ejemplo comprueba


@@ERROR después de una
instrucción INSERT de un procedimiento almacenado. El


valor de la variable
@@ERROR determina el código de retorno enviado al


programa que llamó, lo que
indica el éxito o el fracaso del procedimiento.

USE pubs
GO

CREATE PROCEDURE add_author
@au_id varchar(11),@au_lname varchar(40),
@au_fname varchar(20),@phone char(12),
@address varchar(40) = NULL,@city varchar(20) = NULL,
@state char(2) = NULL,@zip char(5) = NULL,
@contract bit = NULL
AS

INSERT INTO authors
(au_id, au_lname, au_fname, phone, address,
city, state, zip, contract) values
(@au_id,@au_lname,@au_fname,@phone,@address,
@city,@state,@zip,@contract)

IF @@ERROR <> 0
BEGIN


failure.
PRINT "An error occurred loading the new author


information"
RETURN(99)
END
ELSE
BEGIN
PRINT "The new author information has been loaded"
RETURN(0)
END
GO
C. Utilizar @@ERROR para comprobar el éxito de varias


instrucciones
Este ejemplo depende de la ejecución con éxito de las


instrucciones INSERT y
DELETE. Se establece el valor de @@ERROR en variables


locales después de
ambas instrucciones y se utilizan las variables en una


rutina de tratamiento
de errores común para la operación.

USE pubs
GO
DECLARE @del_error int, @ins_error int
BEGIN TRAN

DELETE authors
WHERE au_id = '409-56-7088'

SELECT @del_error = @@ERROR

INSERT authors
VALUES('409-56-7008', 'Bennet', 'Abraham', '415 658-


9932',
'6223 Bateman St.', 'Berkeley', 'CA', '94705', 1)
SELECT @ins_error = @@ERROR

IF @del_error = 0 AND @ins_error = 0
BEGIN
PRINT "The author information has been replaced"
COMMIT TRAN
END
ELSE
BEGIN


failed
IF @del_error <> 0
PRINT "An error occurred during execution of the


DELETE
statement."

IF @ins_error <> 0
PRINT "An error occurred during execution of the


INSERT
statement."

ROLLBACK TRAN
END
GO
D. Utilizar @@ERROR con @@ROWCOUNT
Este ejemplo utiliza @@ERROR con @@ROWCOUNT para validar


la operación de una
instrucción UPDATE. Se comprueba el valor de @@ERROR para


ver si hay un
error y se utiliza @@ROWCOUNT para asegurar que la


actualización se aplica
correctamente a una fila de la tabla.

USE pubs
GO
CREATE PROCEDURE change_publisher
@title_id tid,
@new_pub_id char(4)
AS

DECLARE @error_var int, @rowcount_var int

UPDATE titles SET pub_id = @new_pub_id
WHERE title_id = @title_id

SELECT @error_var = @@ERROR, @rowcount_var = @@ROWCOUNT



specified
error #547.
IF @error_var <> 0
BEGIN
IF @error_var = 547
BEGIN
PRINT "ERROR: Invalid ID specified for new


publisher"
RETURN(1)
END
ELSE
BEGIN
PRINT "ERROR: Unhandled error occurred"
RETURN(2)
END
END

IF @rowcount_var = 0
BEGIN
PRINT "Warning: The title_id specified is not valid"
RETURN(1)
END
ELSE
BEGIN
PRINT "The book has been updated with the new


publisher"
RETURN(0)
END
GO




Maxi

Buenos Aires - Argentina
Desarrollador .NET 3 Estrellas
Microsoft User Group (MUG)
Mail: Maxi_accotto[arroba]speedy.com.ar
Msn Messager:

"fco" escribió en


el mensaje
news:185e01c499eb$1ee33eb0$
Gracias a los que respondieron.

La solucion a este problema es que siempre estuvo
correcto... trabajo hace años con esta instruccion para
deshacer transacciones, creo que debe ser el sueño, ademas
a quien no le ha pasado algo así.

El problema esta cuando quieres actualizar o seleccionar
algo de una tabla que no existe
"update tabla_que_no_existe set campo1= 1"
entonces, en ese caso la transaccion no queda confirmada,
pero si introducimos un valor numerico por ejemplo en un
campo caracter se va a generar el error y entonces deshace
todas las operaciones.

Estuve leyendo sus respuestas y gracias, pero creo que lo
que yo coloco al final de todas las instruciones es lo
mejor. Si se dan cuenta yo sólo coloco una vez al final el
IF @@ERROR <> 0
ROLLBACK
ELSE
commit
..entonces no tenemos que colocarlo despues de cada
ejecucion.
instruccion es correcta, si dio un error en una sentencia
y si las demas estan correctas, se quedara con el valor
que genero el error.

¿En que estaba pensando, si esta instruccón como mencioné
la saque de la ayuda o de un libro de SQL SERVER (ya no me
acuerdo )? Obvio que tenía que estar correcta la
instruccion.



en el siguiente proc. almacenado:

begin tran

update tabla1 set campo1= 1
update tabla2 set campo1= 1

IF @@ERROR <> 0
ROLLBACK
ELSE
commit

se supone que si una instruccion falla @error es distinto
de 0, entonces deshace la transaccion con rollback, pero
en lugar de eso se ejecuta la instruccion que no falla y
ademas no confirma la transaccion y me arroja el


siguiente
error:

"El recuento de transacciones después de EXECUTE indica
que falta una instrucción COMMIT o ROLLBACK TRANSACTION.
Recuento anterior = 1, recuento actual = 2."

¿alguien sabe como confirmar o deshacer las


transacciones,
porque este ejemplo lo saque de la ayuda y no ma habia
dado cuenta que no funciona?

instrucciones obviamente la deshace, pero si esta despues
del if @error ... no lo reconoce..



.





.

Respuesta Responder a este mensaje
#9 ulises
14/09/2004 - 07:10 | Informe spam
Ahí también hay un error, cuando marcas BEGIN TRAN estás dando inicio
a una transacción explícita por lo tanto es necesario realizar un
COMMIT, en caso que no se realice, al final de la conexión se produce
un ROLLBACK automático de la transacción así no se haya producido
errores en su ejecución.

Saludos,
Ulises

On Mon, 13 Sep 2004 18:34:27 -0700, "fco"
wrote:

ok, tienes razon.
Hasta, me di cuenta que ni siquiera es necesario colocar
esa instruccion, porque con sólo colocar
"Begin tran"
el sql server es el que se encarga de confirmarlas o
deshacerlas si se produce un error, si esta configurado
para confirmar las transacciones automaticamente (que en
la instalacion viene por defecto), o sea no es necesario
colocar commit o rollback ... Excepto si son transacciones
anidadas.

Respuesta Responder a este mensaje
#10 fco
14/09/2004 - 13:50 | Informe spam
perdon el "o sea no es necesario
colocar commit o rollback ...", era un
if @@error <> o
rollback
else
commit

lo estuve provando antes de enviar el mensaje, sólo le
colocas begin tran y commit al final, no es necesario
preguntar por el @@error.

Ahí también hay un error, cuando marcas BEGIN TRAN estás


dando inicio
a una transacción explícita por lo tanto es necesario


realizar un
COMMIT, en caso que no se realice, al final de la


conexión se produce
un ROLLBACK automático de la transacción así no se haya


producido
errores en su ejecución.

Saludos,
Ulises

On Mon, 13 Sep 2004 18:34:27 -0700, "fco"
wrote:

ok, tienes razon.
Hasta, me di cuenta que ni siquiera es necesario colocar
esa instruccion, porque con sólo colocar
"Begin tran"
el sql server es el que se encarga de confirmarlas o
deshacerlas si se produce un error, si esta configurado
para confirmar las transacciones automaticamente (que en
la instalacion viene por defecto), o sea no es necesario
colocar commit o rollback ... Excepto si son




transacciones
anidadas.




.

Respuesta Responder a este mensaje
Ads by Google
Help Hacer una preguntaSiguiente AnteriorRespuesta Tengo una respuesta
Search Busqueda sugerida