tablas inserted y deleted con updates multiples

09/09/2008 - 12:15 por joss22 | Informe spam
Hola, tengo un trigger que esta programado para realizar ciertas
operaciones tras insert, delete and update, siempre considerando que
las tablas inserted y deleted tendran un solo registro.
Por esto, al lanzar un update, deleted o insert masivo, que afecta a n
registros, ocurre que el trigger solo se ejecuta una vez y las tablas
inserted y deleted pueden tener hasta n registros, con lo que mi
trigger deja de funcionar.

¿Se le puede pasar algun parametro a las consultas update, insert y
delete para que si afectan a n registros el trigger se ejecute n veces
y cada vez haya como maximo un registro en inserted y deleted?

gracias

Preguntas similare

Leer las respuestas

#1 Maxi Accotto
09/09/2008 - 15:14 | Informe spam
Jos, lo que usted debe hacer es que el trigger funcione para mas de un
registro, sino siempre tendra el problema que usted comenta.




Saludos
Maxi Accotto
Microsoft MVP en SQLServer
SQltotalconsulting
-

"joss22" escribió en el mensaje de
noticias:
Hola, tengo un trigger que esta programado para realizar ciertas
operaciones tras insert, delete and update, siempre considerando que
las tablas inserted y deleted tendran un solo registro.
Por esto, al lanzar un update, deleted o insert masivo, que afecta a n
registros, ocurre que el trigger solo se ejecuta una vez y las tablas
inserted y deleted pueden tener hasta n registros, con lo que mi
trigger deja de funcionar.

¿Se le puede pasar algun parametro a las consultas update, insert y
delete para que si afectan a n registros el trigger se ejecute n veces
y cada vez haya como maximo un registro en inserted y deleted?

gracias
Respuesta Responder a este mensaje
#2 Alejandro Mesa
09/09/2008 - 15:42 | Informe spam
joss22,

Los triggers se disparan por cada operacion involucrada, y no por cada fila
afectada por la operacion. Debes tener en cuenta que mas de una fila puede
ser afectada por una operacion DML.

Si te es posible, postea el codigo para tener una idea de lo que deseas
hacer yde seguro algun miembreo de este grupo podra darte una sugerencia.

Ve si este hilo te sirve de ayuda.

Trigger para Delete
http://www.microsoft.com/communitie...er&midÅ9d2b1e-3bc6-4d40-8f7e-1b06b93ada60&sloc=en-us


AMB


"joss22" wrote:

Hola, tengo un trigger que esta programado para realizar ciertas
operaciones tras insert, delete and update, siempre considerando que
las tablas inserted y deleted tendran un solo registro.
Por esto, al lanzar un update, deleted o insert masivo, que afecta a n
registros, ocurre que el trigger solo se ejecuta una vez y las tablas
inserted y deleted pueden tener hasta n registros, con lo que mi
trigger deja de funcionar.

¿Se le puede pasar algun parametro a las consultas update, insert y
delete para que si afectan a n registros el trigger se ejecute n veces
y cada vez haya como maximo un registro en inserted y deleted?

gracias

Respuesta Responder a este mensaje
#3 Rubén Garrigós
09/09/2008 - 16:19 | Informe spam
Efectivamente como ya te han apuntado Maxi y Alejandro la solución correcta
es modificar el cuerpo del trigger para que funcione con 1 o con N filas.

En algunos casos puede interesarte tener lógica diferente para el caso 1 o N
lo cual lo puedes solucionar fácilmente comparando con @@rowcount. Por otra
parte, en el caso que lo que tenga que hacer el trigger deba ser
ABSOLUTAMENTE necesario fila a fila (podría darse el caso) siempre puedes
recurrir a encapsular la actual lógica del trigger en un procedimiento
almacenado. De esta forma en el caso de @@rowcount=1 simplemente ejecutarías
el procedimiento una vez y en el caso de N filas podrías iterar con un cursor
llamando a dicho procedimiento.

Mucho cuidado con esta alternativa pues puede penalizar mucho el rendimiento
y debe ser evitada siempre que sea posible encontrar una solución orientada a
conjunto de filas sin cursor de por medio.

Rubén Garrigós
Solid Quality Mentors


"joss22" wrote:

Hola, tengo un trigger que esta programado para realizar ciertas
operaciones tras insert, delete and update, siempre considerando que
las tablas inserted y deleted tendran un solo registro.
Por esto, al lanzar un update, deleted o insert masivo, que afecta a n
registros, ocurre que el trigger solo se ejecuta una vez y las tablas
inserted y deleted pueden tener hasta n registros, con lo que mi
trigger deja de funcionar.

¿Se le puede pasar algun parametro a las consultas update, insert y
delete para que si afectan a n registros el trigger se ejecute n veces
y cada vez haya como maximo un registro en inserted y deleted?

gracias

Respuesta Responder a este mensaje
#4 joss22
09/09/2008 - 17:08 | Informe spam
Vale. En tal caso creo que lo mejor es (como habeis comentado) que
explique con mas detalle que es lo que pretendo de manera que sea mas
facil encontrar una solucion.

Este trigger lo que hace es:

1) lanza un select a las tablas inserted y deleted y las convierte a
xml.

SET @oldValueXML = (SELECT * FROM deleted FOR XML AUTO,
ELEMENTS)
SET @newValueXML = (SELECT * FROM inserted FOR XML
AUTO ,ELEMENTS)
el objetivo es tener un registro de los cambios que se han producido

2) lanza un insert a una tabla "auditoria" donde entre otras cosas
guarda, la fecha, el nombre de la tabla, valor de su pk, y en el campo
oldvalues mete @oldValueXML y en el campo newvalues mete
@newValueXML.


Lo que ocurre cuando hay mas de un registro en inserted o deleted es
que los xml's resultantes contienes TODOS los cambios producidos en
todos los registros que se han visto afectados y posteriormente se
crea UN registro en auditoria.

Espero que os sirva para entender mejor mi problema. Un saludo y
gracias por responder.
Respuesta Responder a este mensaje
#5 Rubén Garrigós
09/09/2008 - 17:55 | Informe spam
Podrías pues sustituir el insert del trigger por algo así:

insert into auditoria (fecha, tabla, pk, oldvalues, newvalues)
select getdate(), 'tabla', pk,
(SELECT * FROM deleted as d where d.pk=cambios.pk FOR XML AUTO,
ELEMENTS) ,
(SELECT * FROM inserted as i where i.pk=cambios.pk FOR XML AUTO,
ELEMENTS)
from
(
select pk from inserted
union
select pk from deleted
) cambios

No es lo más eficiente del mundo pero debería funcionar. También ten en
cuenta que un cambio de pk quedaría mal reflejado. Te recomendaría añadir una
columna para la pk-inserted y otra para la pk-deleted.

Finalmente, almacenar esta información como XML y en un trigger añadirá
cierta carga extra al proceso por lo cual... ¿podría quizás plantearse el
almacenarlo como una tabla de control de cambios con sus tipos
correspondientes a la tabla monitorizada? Al fin y al cabo, la PK por ejemplo
la deberás configurar a mano por cada tabla...

Rubén Garrigós
Solid Quality Mentors

"joss22" wrote:

Vale. En tal caso creo que lo mejor es (como habeis comentado) que
explique con mas detalle que es lo que pretendo de manera que sea mas
facil encontrar una solucion.

Este trigger lo que hace es:

1) lanza un select a las tablas inserted y deleted y las convierte a
xml.

SET @oldValueXML = (SELECT * FROM deleted FOR XML AUTO,
ELEMENTS)
SET @newValueXML = (SELECT * FROM inserted FOR XML
AUTO ,ELEMENTS)
el objetivo es tener un registro de los cambios que se han producido

2) lanza un insert a una tabla "auditoria" donde entre otras cosas
guarda, la fecha, el nombre de la tabla, valor de su pk, y en el campo
oldvalues mete @oldValueXML y en el campo newvalues mete
@newValueXML.


Lo que ocurre cuando hay mas de un registro en inserted o deleted es
que los xml's resultantes contienes TODOS los cambios producidos en
todos los registros que se han visto afectados y posteriormente se
crea UN registro en auditoria.

Espero que os sirva para entender mejor mi problema. Un saludo y
gracias por responder.

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