1 UPDATE de n columnas lanza n veces el trigger, y yo quiero 1!

27/04/2005 - 10:46 por Jose | Informe spam
Hola, estoy trabajando en SQL SERVER 2000, e intentando almacenar en varias
tablas (1 por columna), el historico de actualizaciones por cada columna de
la tabla "madre".
El problema: el trigger se lanza n veces, tantas como columnas se
actualizan, luego en las tablas historicas se almacena n veces ese cambio.
Debido a que utilizando la funcion COLUMNS_UPDATED(), mapeo las columnas
actualizadas y lanzo el registro para cada una.
¿Como debería hacerlo para que sólo se almacenara 1 vez, o para que el
trigger solo se lanzara 1 única vez?

Muchas gracias, aquí os adjunto el codigo:

************************************************************
/*
- El MAPA de columnas es:
c1 0000 0001 = 1
c2 0000 0010 = 2
c3 0000 0100 = 4
c4 0000 1000 = 8
c5 0001 0000 = 16
c6 0010 0000 = 32
*/

CREATE TRIGGER trig_GuardaHistoricoModifs
ON MyTable
FOR UPDATE
AS

declare @fila smallint
declare @fecha datetime
declare @columnas integer

SET @fecha = getdate() /* Establecer la fecha para que sea
la misma en todas las inserciones,
y no varíe ni en los segundos */

/* Convertir COLUMNS_UPDATED() que es varbinary en integer para las
comparaciones */
SET @columnas = convert( integer, COLUMNS_UPDATED() )

/* Modificacion de la 1ª columna */
IF ( ( @columnas & convert(integer, 0x01) ) = 1 )
BEGIN
INSERT INTO HistModifMyTable_C1
SELECT @fecha as Fecha, I.usuario, D.dato1, D.dato2, I.dato3
FROM inserted I, deleted D
END

/* Modificacion de la 2ª columna */
IF ( ( @columnas & convert(integer, 0x02) ) = 2 )
BEGIN
INSERT INTO HistModifMyTable_C2
SELECT @fecha as Fecha, I.usuario, D.dato1, D.dato2, I.dato3
FROM inserted I, deleted D
END

/* Modificacion de la 3ª columna */
IF ( ( @columnas & convert(integer, 0x04) ) = 4 )
BEGIN
INSERT INTO HistModifMyTable_C3
SELECT @fecha as Fecha, I.usuario, D.dato1, D.dato2, I.dato3
FROM inserted I, deleted D
END
GO
************************************************************

Preguntas similare

Leer las respuestas

#1 Jose
27/04/2005 - 11:08 | Informe spam
Ya está solucionado.
Resulta que el trigger trabaja correctamente (ya me parecía a mí muy extraña
la conclusión a la que había llegado), lo que pasa es que había otra
inserción de modificaciones en otra función.

Muchas gracias por atenderme.

"Jose" escribió:

Hola, estoy trabajando en SQL SERVER 2000, e intentando almacenar en varias
tablas (1 por columna), el historico de actualizaciones por cada columna de
la tabla "madre".
El problema: el trigger se lanza n veces, tantas como columnas se
actualizan, luego en las tablas historicas se almacena n veces ese cambio.
Debido a que utilizando la funcion COLUMNS_UPDATED(), mapeo las columnas
actualizadas y lanzo el registro para cada una.
¿Como debería hacerlo para que sólo se almacenara 1 vez, o para que el
trigger solo se lanzara 1 única vez?

Muchas gracias, aquí os adjunto el codigo:

************************************************************
/*
- El MAPA de columnas es:
c1 0000 0001 = 1
c2 0000 0010 = 2
c3 0000 0100 = 4
c4 0000 1000 = 8
c5 0001 0000 = 16
c6 0010 0000 = 32
*/

CREATE TRIGGER trig_GuardaHistoricoModifs
ON MyTable
FOR UPDATE
AS

declare @fila smallint
declare @fecha datetime
declare @columnas integer

SET @fecha = getdate() /* Establecer la fecha para que sea
la misma en todas las inserciones,
y no varíe ni en los segundos */

/* Convertir COLUMNS_UPDATED() que es varbinary en integer para las
comparaciones */
SET @columnas = convert( integer, COLUMNS_UPDATED() )

/* Modificacion de la 1ª columna */
IF ( ( @columnas & convert(integer, 0x01) ) = 1 )
BEGIN
INSERT INTO HistModifMyTable_C1
SELECT @fecha as Fecha, I.usuario, D.dato1, D.dato2, I.dato3
FROM inserted I, deleted D
END

/* Modificacion de la 2ª columna */
IF ( ( @columnas & convert(integer, 0x02) ) = 2 )
BEGIN
INSERT INTO HistModifMyTable_C2
SELECT @fecha as Fecha, I.usuario, D.dato1, D.dato2, I.dato3
FROM inserted I, deleted D
END

/* Modificacion de la 3ª columna */
IF ( ( @columnas & convert(integer, 0x04) ) = 4 )
BEGIN
INSERT INTO HistModifMyTable_C3
SELECT @fecha as Fecha, I.usuario, D.dato1, D.dato2, I.dato3
FROM inserted I, deleted D
END
GO
************************************************************
Respuesta Responder a este mensaje
#2 Carlos Sacristán
27/04/2005 - 11:19 | Informe spam
El trigger no se lanza una vez por columna actualizada, sino por
operación de modificación de datos que se realice. Es decir, que el trigger
saltará una única vez aunque la sentencia de modificación afecte a uno o a
cientos de registros (que se reflejarán en las tablas deleted e inserted)

En tu código tendrías que tener en cuenta la posibilidad de que te
actualicen más de un registro, porque es algo que no tienes controlado al no
hacer un INNER JOIN entre Inserted y Deleted


Un saludo

-
"Sólo sé que no sé nada. " (Sócrates)

"Jose" escribió en el mensaje
news:
Hola, estoy trabajando en SQL SERVER 2000, e intentando almacenar en


varias
tablas (1 por columna), el historico de actualizaciones por cada columna


de
la tabla "madre".
El problema: el trigger se lanza n veces, tantas como columnas se
actualizan, luego en las tablas historicas se almacena n veces ese cambio.
Debido a que utilizando la funcion COLUMNS_UPDATED(), mapeo las columnas
actualizadas y lanzo el registro para cada una.
¿Como debería hacerlo para que sólo se almacenara 1 vez, o para que el
trigger solo se lanzara 1 única vez?

Muchas gracias, aquí os adjunto el codigo:

************************************************************
/*
- El MAPA de columnas es:
c1 0000 0001 = 1
c2 0000 0010 = 2
c3 0000 0100 = 4
c4 0000 1000 = 8
c5 0001 0000 = 16
c6 0010 0000 = 32
*/

CREATE TRIGGER trig_GuardaHistoricoModifs
ON MyTable
FOR UPDATE
AS

declare @fila smallint
declare @fecha datetime
declare @columnas integer

SET @fecha = getdate() /* Establecer la fecha para que sea
la misma en todas las inserciones,
y no varíe ni en los segundos */

/* Convertir COLUMNS_UPDATED() que es varbinary en integer para las
comparaciones */
SET @columnas = convert( integer, COLUMNS_UPDATED() )

/* Modificacion de la 1ª columna */
IF ( ( @columnas & convert(integer, 0x01) ) = 1 )
BEGIN
INSERT INTO HistModifMyTable_C1
SELECT @fecha as Fecha, I.usuario, D.dato1, D.dato2, I.dato3
FROM inserted I, deleted D
END

/* Modificacion de la 2ª columna */
IF ( ( @columnas & convert(integer, 0x02) ) = 2 )
BEGIN
INSERT INTO HistModifMyTable_C2
SELECT @fecha as Fecha, I.usuario, D.dato1, D.dato2, I.dato3
FROM inserted I, deleted D
END

/* Modificacion de la 3ª columna */
IF ( ( @columnas & convert(integer, 0x04) ) = 4 )
BEGIN
INSERT INTO HistModifMyTable_C3
SELECT @fecha as Fecha, I.usuario, D.dato1, D.dato2, I.dato3
FROM inserted I, deleted D
END
GO
************************************************************
Respuesta Responder a este mensaje
#3 Jose
27/04/2005 - 12:48 | Informe spam
Grácias Carlos, es cierto todo lo que dices, de hecho, es algo que yo antes
tenía muy claro, pero de no usarlo..., ha sido una mega cruzada de cables.
De todas maneras, gracias por el consejo, cierto es que el Join me dará
problemas, ahora mismo lo cambio para contemplarlo. Aunque sólamente
actualice 1! registro, quien sabe si el día de mañana ... .

"Carlos Sacristán" escribió:

El trigger no se lanza una vez por columna actualizada, sino por
operación de modificación de datos que se realice. Es decir, que el trigger
saltará una única vez aunque la sentencia de modificación afecte a uno o a
cientos de registros (que se reflejarán en las tablas deleted e inserted)

En tu código tendrías que tener en cuenta la posibilidad de que te
actualicen más de un registro, porque es algo que no tienes controlado al no
hacer un INNER JOIN entre Inserted y Deleted


Un saludo

-
"Sólo sé que no sé nada. " (Sócrates)

"Jose" escribió en el mensaje
news:
> Hola, estoy trabajando en SQL SERVER 2000, e intentando almacenar en
varias
> tablas (1 por columna), el historico de actualizaciones por cada columna
de
> la tabla "madre".
> El problema: el trigger se lanza n veces, tantas como columnas se
> actualizan, luego en las tablas historicas se almacena n veces ese cambio.
> Debido a que utilizando la funcion COLUMNS_UPDATED(), mapeo las columnas
> actualizadas y lanzo el registro para cada una.
> ¿Como debería hacerlo para que sólo se almacenara 1 vez, o para que el
> trigger solo se lanzara 1 única vez?
>
> Muchas gracias, aquí os adjunto el codigo:
>
> ************************************************************
> /*
> - El MAPA de columnas es:
> c1 0000 0001 = 1
> c2 0000 0010 = 2
> c3 0000 0100 = 4
> c4 0000 1000 = 8
> c5 0001 0000 = 16
> c6 0010 0000 = 32
> */
>
> CREATE TRIGGER trig_GuardaHistoricoModifs
> ON MyTable
> FOR UPDATE
> AS
>
> declare @fila smallint
> declare @fecha datetime
> declare @columnas integer
>
> SET @fecha = getdate() /* Establecer la fecha para que sea
> la misma en todas las inserciones,
> y no varíe ni en los segundos */
>
> /* Convertir COLUMNS_UPDATED() que es varbinary en integer para las
> comparaciones */
> SET @columnas = convert( integer, COLUMNS_UPDATED() )
>
> /* Modificacion de la 1ª columna */
> IF ( ( @columnas & convert(integer, 0x01) ) = 1 )
> BEGIN
> INSERT INTO HistModifMyTable_C1
> SELECT @fecha as Fecha, I.usuario, D.dato1, D.dato2, I.dato3
> FROM inserted I, deleted D
> END
>
> /* Modificacion de la 2ª columna */
> IF ( ( @columnas & convert(integer, 0x02) ) = 2 )
> BEGIN
> INSERT INTO HistModifMyTable_C2
> SELECT @fecha as Fecha, I.usuario, D.dato1, D.dato2, I.dato3
> FROM inserted I, deleted D
> END
>
> /* Modificacion de la 3ª columna */
> IF ( ( @columnas & convert(integer, 0x04) ) = 4 )
> BEGIN
> INSERT INTO HistModifMyTable_C3
> SELECT @fecha as Fecha, I.usuario, D.dato1, D.dato2, I.dato3
> FROM inserted I, deleted D
> END
> GO
> ************************************************************



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