Que no os den problemas los triggers.

23/11/2003 - 23:12 por Jorge Viñuales | Informe spam
Hace tiempo que tengo funcionando un par de aplicaciones hechas bajo SQL
Server. Os comento un par de conclusiones que he sacado, muy interesantes
acerca del trabajo con triggers.

Estas potentísimas herramientas de SQL, si no se miman mucho pueden dar más
problemas que alegrías.

Primero os diré dos cláusulas que tienen que ir siempre al principio de casi
cualquier trigger (justo después del as) y luego os explico porqué.

if @@rowcount = 0
return

set nocount on

Lo primero es porque muchas veces, puede desencadenarse un trigger de una
tabla, cuando en realidad no ha habido ninguna fila afectada en la acción
que lo ha desencadenado. Por ejemplo, cuando hay dos tablas A y B con una
relación, y tienen activada la opción actualización o eliminación en
cascada, al realizar una modificación en la tabla A, aunque no afecte a
ningún registro de la tabla B los triggers saltan. Si no habéis previsto en
el código del trigger que puede no haber filas afectadas se pueden producir
resultados inesperados (como me ha pasado a mi). Utilizando el control (if
@@rowcount = 0), se consigue que no se ejecute el código del trigger a no
ser que sea realmente necesario.

La segunda es fundamental si trabajáis con ADO. No solo para evitar que se
manden mensajes innecesarios al cliente, sino porque he comprobado que
muchas veces, ADO se vuelve loco (sobre todo con los mensajes de error) al
recibir los mensajes innecesarios que se generan dentro del trigger. Y esto
vale también para storeds.

Saludos y espero que os evite alguno de los problemas que yo he tenido por
culpa de esto.

Preguntas similare

Leer las respuestas

#1 Miguel Egea
24/11/2003 - 10:19 | Informe spam
Hola Jorge, gracias por conpartir con nosotros tus experiencias,

me surgen un par de comentarios/dudas
1.- Sobre set nocount on absolutamente de acuerdo, menos viajes entre
cliente y servidor.

Sin embargo sobre el @@rowcount, cuando he visto problemas con esto siempre
ha sido porque no se hacía un uso adecuado de inserted y deleted, pensando
que solamente contenían un registro (y siempre 1), instrucciones como select
@valor=campo from inserted, si este es el caso, no lo solucionaría
@@rowcount.

En cualquiera de los casos esto es lo que digo como tu bien dices en base a
mi experiencia.


Saludos

Miguel Egea
Microsoft SQL-SERVER MVP
Brigada Anti-Cursores

"Jorge Viñuales" escribió en el mensaje
news:
Hace tiempo que tengo funcionando un par de aplicaciones hechas bajo SQL
Server. Os comento un par de conclusiones que he sacado, muy interesantes
acerca del trabajo con triggers.

Estas potentísimas herramientas de SQL, si no se miman mucho pueden dar


más
problemas que alegrías.

Primero os diré dos cláusulas que tienen que ir siempre al principio de


casi
cualquier trigger (justo después del as) y luego os explico porqué.

if @@rowcount = 0
return

set nocount on

Lo primero es porque muchas veces, puede desencadenarse un trigger de una
tabla, cuando en realidad no ha habido ninguna fila afectada en la acción
que lo ha desencadenado. Por ejemplo, cuando hay dos tablas A y B con una
relación, y tienen activada la opción actualización o eliminación en
cascada, al realizar una modificación en la tabla A, aunque no afecte a
ningún registro de la tabla B los triggers saltan. Si no habéis previsto


en
el código del trigger que puede no haber filas afectadas se pueden


producir
resultados inesperados (como me ha pasado a mi). Utilizando el control (if
@@rowcount = 0), se consigue que no se ejecute el código del trigger a no
ser que sea realmente necesario.

La segunda es fundamental si trabajáis con ADO. No solo para evitar que se
manden mensajes innecesarios al cliente, sino porque he comprobado que
muchas veces, ADO se vuelve loco (sobre todo con los mensajes de error) al
recibir los mensajes innecesarios que se generan dentro del trigger. Y


esto
vale también para storeds.

Saludos y espero que os evite alguno de los problemas que yo he tenido por
culpa de esto.


Respuesta Responder a este mensaje
#2 Jorge Viñuales
24/11/2003 - 23:02 | Informe spam
Hola Miguel.

El problema que yo he tenido con respecto a lo que comentas no es el hecho
de no controlar que pueda haber más de 1 registro afectado por la acción,
sino que en ciertas circunstancias, SQL Server lanza un trigger sin que en
realidad haya habido ninguna fila afectada en la acción que lo ha
desencadenado. Si mal no recuerdo, esto me pasaba cuando tenía una relación
entre dos tablas con la actualización o eliminación en cascada activadas
(algo que puede ser muy habitual).
Si eliminar un registro de cabecera de pedidos (por ejemplo) y este no
contiene registros relacionados en la tabla de líneas, a pesar de no
producirse ninguna eliminación real en la tabla de líneas (por que no había
lineas de ese pedido), los triggers de eliminación si que saltaban (en la
tabla de líneas). Como este caso en concreto no lo había tenido en cuenta en
el código del trigger (la tabla deleted estaba vacía, a pesar de que se
supone que ha habido una eliminación) me hacía cosas muy raras, y me
producía errores en las reglas de negocio. Además que sentido tiene ejecutar
todo un código, que puede estar consumiendo recursos si en realidad no se ha
eliminado nada?.

A ver que opinas. Voy a intentar generar un script que reproduzca esta
situación para que lo veais.

Saludos






"Miguel Egea" escribió en el mensaje
news:
Hola Jorge, gracias por conpartir con nosotros tus experiencias,

me surgen un par de comentarios/dudas
1.- Sobre set nocount on absolutamente de acuerdo, menos viajes entre
cliente y servidor.

Sin embargo sobre el @@rowcount, cuando he visto problemas con esto


siempre
ha sido porque no se hacía un uso adecuado de inserted y deleted, pensando
que solamente contenían un registro (y siempre 1), instrucciones como


select
@valor=campo from inserted, si este es el caso, no lo solucionaría
@@rowcount.

En cualquiera de los casos esto es lo que digo como tu bien dices en base


a
mi experiencia.


Saludos

Miguel Egea
Microsoft SQL-SERVER MVP
Brigada Anti-Cursores

"Jorge Viñuales" escribió en el mensaje
news:
> Hace tiempo que tengo funcionando un par de aplicaciones hechas bajo SQL
> Server. Os comento un par de conclusiones que he sacado, muy


interesantes
> acerca del trabajo con triggers.
>
> Estas potentísimas herramientas de SQL, si no se miman mucho pueden dar
más
> problemas que alegrías.
>
> Primero os diré dos cláusulas que tienen que ir siempre al principio de
casi
> cualquier trigger (justo después del as) y luego os explico porqué.
>
> if @@rowcount = 0
> return
>
> set nocount on
>
> Lo primero es porque muchas veces, puede desencadenarse un trigger de


una
> tabla, cuando en realidad no ha habido ninguna fila afectada en la


acción
> que lo ha desencadenado. Por ejemplo, cuando hay dos tablas A y B con


una
> relación, y tienen activada la opción actualización o eliminación en
> cascada, al realizar una modificación en la tabla A, aunque no afecte a
> ningún registro de la tabla B los triggers saltan. Si no habéis previsto
en
> el código del trigger que puede no haber filas afectadas se pueden
producir
> resultados inesperados (como me ha pasado a mi). Utilizando el control


(if
> @@rowcount = 0), se consigue que no se ejecute el código del trigger a


no
> ser que sea realmente necesario.
>
> La segunda es fundamental si trabajáis con ADO. No solo para evitar que


se
> manden mensajes innecesarios al cliente, sino porque he comprobado que
> muchas veces, ADO se vuelve loco (sobre todo con los mensajes de error)


al
> recibir los mensajes innecesarios que se generan dentro del trigger. Y
esto
> vale también para storeds.
>
> Saludos y espero que os evite alguno de los problemas que yo he tenido


por
> culpa de esto.
>
>


Respuesta Responder a este mensaje
#3 Miguel Egea
25/11/2003 - 09:18 | Informe spam
Yo he usado cosas parecidas sin problemas, si nos pasas el código vemos que
sucede..

Saludos
Miguel Egea
"Jorge Viñuales" escribió en el mensaje
news:
Hola Miguel.

El problema que yo he tenido con respecto a lo que comentas no es el hecho
de no controlar que pueda haber más de 1 registro afectado por la acción,
sino que en ciertas circunstancias, SQL Server lanza un trigger sin que en
realidad haya habido ninguna fila afectada en la acción que lo ha
desencadenado. Si mal no recuerdo, esto me pasaba cuando tenía una


relación
entre dos tablas con la actualización o eliminación en cascada activadas
(algo que puede ser muy habitual).
Si eliminar un registro de cabecera de pedidos (por ejemplo) y este no
contiene registros relacionados en la tabla de líneas, a pesar de no
producirse ninguna eliminación real en la tabla de líneas (por que no


había
lineas de ese pedido), los triggers de eliminación si que saltaban (en la
tabla de líneas). Como este caso en concreto no lo había tenido en cuenta


en
el código del trigger (la tabla deleted estaba vacía, a pesar de que se
supone que ha habido una eliminación) me hacía cosas muy raras, y me
producía errores en las reglas de negocio. Además que sentido tiene


ejecutar
todo un código, que puede estar consumiendo recursos si en realidad no se


ha
eliminado nada?.

A ver que opinas. Voy a intentar generar un script que reproduzca esta
situación para que lo veais.

Saludos






"Miguel Egea" escribió en el mensaje
news:
> Hola Jorge, gracias por conpartir con nosotros tus experiencias,
>
> me surgen un par de comentarios/dudas
> 1.- Sobre set nocount on absolutamente de acuerdo, menos viajes entre
> cliente y servidor.
>
> Sin embargo sobre el @@rowcount, cuando he visto problemas con esto
siempre
> ha sido porque no se hacía un uso adecuado de inserted y deleted,


pensando
> que solamente contenían un registro (y siempre 1), instrucciones como
select
> @valor=campo from inserted, si este es el caso, no lo solucionaría
> @@rowcount.
>
> En cualquiera de los casos esto es lo que digo como tu bien dices en


base
a
> mi experiencia.
>
>
> Saludos
>
> Miguel Egea
> Microsoft SQL-SERVER MVP
> Brigada Anti-Cursores
>
> "Jorge Viñuales" escribió en el mensaje
> news:
> > Hace tiempo que tengo funcionando un par de aplicaciones hechas bajo


SQL
> > Server. Os comento un par de conclusiones que he sacado, muy
interesantes
> > acerca del trabajo con triggers.
> >
> > Estas potentísimas herramientas de SQL, si no se miman mucho pueden


dar
> más
> > problemas que alegrías.
> >
> > Primero os diré dos cláusulas que tienen que ir siempre al principio


de
> casi
> > cualquier trigger (justo después del as) y luego os explico porqué.
> >
> > if @@rowcount = 0
> > return
> >
> > set nocount on
> >
> > Lo primero es porque muchas veces, puede desencadenarse un trigger de
una
> > tabla, cuando en realidad no ha habido ninguna fila afectada en la
acción
> > que lo ha desencadenado. Por ejemplo, cuando hay dos tablas A y B con
una
> > relación, y tienen activada la opción actualización o eliminación en
> > cascada, al realizar una modificación en la tabla A, aunque no afecte


a
> > ningún registro de la tabla B los triggers saltan. Si no habéis


previsto
> en
> > el código del trigger que puede no haber filas afectadas se pueden
> producir
> > resultados inesperados (como me ha pasado a mi). Utilizando el control
(if
> > @@rowcount = 0), se consigue que no se ejecute el código del trigger a
no
> > ser que sea realmente necesario.
> >
> > La segunda es fundamental si trabajáis con ADO. No solo para evitar


que
se
> > manden mensajes innecesarios al cliente, sino porque he comprobado que
> > muchas veces, ADO se vuelve loco (sobre todo con los mensajes de


error)
al
> > recibir los mensajes innecesarios que se generan dentro del trigger. Y
> esto
> > vale también para storeds.
> >
> > Saludos y espero que os evite alguno de los problemas que yo he tenido
por
> > culpa de esto.
> >
> >
>
>


email Siga el debate Respuesta Responder a este mensaje
Ads by Google
Help Hacer una preguntaRespuesta Tengo una respuesta
Search Busqueda sugerida