Trigger for update

07/09/2006 - 20:12 por Paco | Informe spam
Hola a todos.
Antes de nada decir que soy algo novato en sql y estoy haciendo mis primeros
pinitos.
Tengo una bbdd en sql 2005

Tengo las siguientes tablas
T1 : Unidades de medida
UnidadMedida - k

T2: Unidades de medida producto
Producto - k
UnidadMedida - k

T3: Precios proveedor
Proveedor - k
Producto - k
UnidadMedida -k

Tengo una relacion T1-T2 por el campo unidad de medida. Update on cascada

Tengo una relacion T2-T3 por los campos producto y unidad de medida. Update
no acction porque no me deja sql por otras relaciones.

He creado el siguiente trigger en T2 para mantener la integridad referencial

CREATE TRIGGER [U_COMUnidadesMedidaProducto_ProductoUM]
ON [COMUnidadesMedidaProducto]
FOR UPDATE
AS

IF NOT UPDATE(Producto) AND NOT UPDATE(UnidadMedida)
RETURN

declare @actUM varchar(20), @antUM varchar(20)
SELECT @actUM = UnidadMedida FROM Inserted
SELECT @antUM = UnidadMedida FROM Deleted

declare @actProducto varchar(20), @antProducto varchar(20)
SELECT @actProducto = Producto FROM Inserted
SELECT @antProducto = Producto FROM Deleted

UPDATE PreciosProductosProveedor
SET Producto = @actProducto, UnidadMedida = @actUM
FROM Inserted
WHERE PreciosProductosProveedor.Producto = @antProducto AND
PreciosProductosProveedor.UnidadMedida = @antUM

El trigger me funciona sólo para el primer producto que se modifica en T2.
Alguien me podría ayudar y decirme porque solo funciona para el primer
registro que modifica y como podría hacer para que me funcionase para todos
los registros.

Gracias a todos de antemano.

Preguntas similare

Leer las respuestas

#1 Antonio Soto
07/09/2006 - 21:50 | Informe spam
Hola Paco,

LAs líneas de asignación que tienes te devuelven solo un valor, por ejemplo
SELECT @actUM = UnidadMedida FROM Inserted
solo te devolvería el primer valor de la tabla inserted (los nuevos valores
de modificación)

Para resolverlo, al igual que estás añadiendo la talba Inserted en el update
para hacer el join, agrega también la tabla deleted.

Salud2



Antonio Soto
Solid Quality Learning
http://www.sqlu.com
Disclaimer: This communication is an original work and represents my sole
views on the subject. It does not represent the views of any other person
or entity either by inference or direct reference


"Paco" wrote in message
news:
Hola a todos.
Antes de nada decir que soy algo novato en sql y estoy haciendo mis
primeros
pinitos.
Tengo una bbdd en sql 2005

Tengo las siguientes tablas
T1 : Unidades de medida
UnidadMedida - k

T2: Unidades de medida producto
Producto - k
UnidadMedida - k

T3: Precios proveedor
Proveedor - k
Producto - k
UnidadMedida -k

Tengo una relacion T1-T2 por el campo unidad de medida. Update on cascada

Tengo una relacion T2-T3 por los campos producto y unidad de medida.
Update
no acction porque no me deja sql por otras relaciones.

He creado el siguiente trigger en T2 para mantener la integridad
referencial

CREATE TRIGGER [U_COMUnidadesMedidaProducto_ProductoUM]
ON [COMUnidadesMedidaProducto]
FOR UPDATE
AS

IF NOT UPDATE(Producto) AND NOT UPDATE(UnidadMedida)
RETURN

declare @actUM varchar(20), @antUM varchar(20)
SELECT @actUM = UnidadMedida FROM Inserted
SELECT @antUM = UnidadMedida FROM Deleted

declare @actProducto varchar(20), @antProducto varchar(20)
SELECT @actProducto = Producto FROM Inserted
SELECT @antProducto = Producto FROM Deleted

UPDATE PreciosProductosProveedor
SET Producto = @actProducto, UnidadMedida = @actUM
FROM Inserted
WHERE PreciosProductosProveedor.Producto = @antProducto AND
PreciosProductosProveedor.UnidadMedida = @antUM

El trigger me funciona sólo para el primer producto que se modifica en T2.
Alguien me podría ayudar y decirme porque solo funciona para el primer
registro que modifica y como podría hacer para que me funcionase para
todos
los registros.

Gracias a todos de antemano.


Respuesta Responder a este mensaje
#2 Alejandro Mesa
07/09/2006 - 22:32 | Informe spam
Paco,

Ademas de lo dicho por Antonio, quiero agregar que los triggers son
disparados por cada sentencia involucrada y no por cada fila afectada. Por
eso es que debes contemplar la participacion de multiples filas cuando
programamos un trigger.

Lo otro que quiero comentar es que se hace muy pero muy dificil hacer este
tipo de cosas cuando lo que estamos modificando es la clave primaria, puesto
que la vinculacion entre las tablas "deleted" e "inserted" se pierde. No hay
manera de vincular los nuevos valores de la clave primaria con los viejos
valores, por lo que no sabemos cual de las filas en la tabla inserted
corresponde con que fila de la tabla t3. Para estos casos se hace muy
practico el uso de una clave subrrogada, la cual no se permite modificar y
que es usada por la integridad referencial.

create table dbo.t2 (
sk int not null identity unique,
producto ...,
unidad_medida ...
)

create table dbo.t3 (
proveedor ...,
t2_sk int not null references dbo.t2(sk)
)

Ahora puedes actualizar producto y unidad_medida en t2 sin necesidad de
actualizar t3.


AMB

"Paco" wrote:

Hola a todos.
Antes de nada decir que soy algo novato en sql y estoy haciendo mis primeros
pinitos.
Tengo una bbdd en sql 2005

Tengo las siguientes tablas
T1 : Unidades de medida
UnidadMedida - k

T2: Unidades de medida producto
Producto - k
UnidadMedida - k

T3: Precios proveedor
Proveedor - k
Producto - k
UnidadMedida -k

Tengo una relacion T1-T2 por el campo unidad de medida. Update on cascada

Tengo una relacion T2-T3 por los campos producto y unidad de medida. Update
no acction porque no me deja sql por otras relaciones.

He creado el siguiente trigger en T2 para mantener la integridad referencial

CREATE TRIGGER [U_COMUnidadesMedidaProducto_ProductoUM]
ON [COMUnidadesMedidaProducto]
FOR UPDATE
AS

IF NOT UPDATE(Producto) AND NOT UPDATE(UnidadMedida)
RETURN

declare @actUM varchar(20), @antUM varchar(20)
SELECT @actUM = UnidadMedida FROM Inserted
SELECT @antUM = UnidadMedida FROM Deleted

declare @actProducto varchar(20), @antProducto varchar(20)
SELECT @actProducto = Producto FROM Inserted
SELECT @antProducto = Producto FROM Deleted

UPDATE PreciosProductosProveedor
SET Producto = @actProducto, UnidadMedida = @actUM
FROM Inserted
WHERE PreciosProductosProveedor.Producto = @antProducto AND
PreciosProductosProveedor.UnidadMedida = @antUM

El trigger me funciona sólo para el primer producto que se modifica en T2.
Alguien me podría ayudar y decirme porque solo funciona para el primer
registro que modifica y como podría hacer para que me funcionase para todos
los registros.

Gracias a todos de antemano.


Respuesta Responder a este mensaje
#3 Paco
08/09/2006 - 10:47 | Informe spam
Gracias por la respuesta.
Me ha costado entender lo que me queriais decir pero al final creo que lo he
entendido. He solucionado de este modo, pero no sé si es muy correcto.

He añadido un campo identity en t2 para vincular los registros INSERTED y
DELETED y el trigger me ha quedado de esta forma.

ALTER TRIGGER [dbo].[U_COMUnidadesMedidaProducto_ProductoUM]
ON [dbo].[COMUnidadesMedidaProducto]
FOR UPDATE
AS

IF NOT UPDATE(Producto) AND NOT UPDATE(UnidadMedida)
RETURN


UPDATE COMPreciosProductosProveedor
SET Producto = I.Producto, UnidadMedida = I.UnidadMedida
FROM Inserted AS I
JOIN Deleted AS D ON D.ClaveId = I.ClaveId
WHERE COMPreciosProductosProveedor.Producto = D.Producto AND
COMPreciosProductosProveedor.UnidadMedida = D.UnidadMedida

"Alejandro Mesa" escribió:

Paco,

Ademas de lo dicho por Antonio, quiero agregar que los triggers son
disparados por cada sentencia involucrada y no por cada fila afectada. Por
eso es que debes contemplar la participacion de multiples filas cuando
programamos un trigger.

Lo otro que quiero comentar es que se hace muy pero muy dificil hacer este
tipo de cosas cuando lo que estamos modificando es la clave primaria, puesto
que la vinculacion entre las tablas "deleted" e "inserted" se pierde. No hay
manera de vincular los nuevos valores de la clave primaria con los viejos
valores, por lo que no sabemos cual de las filas en la tabla inserted
corresponde con que fila de la tabla t3. Para estos casos se hace muy
practico el uso de una clave subrrogada, la cual no se permite modificar y
que es usada por la integridad referencial.

create table dbo.t2 (
sk int not null identity unique,
producto ...,
unidad_medida ...
)

create table dbo.t3 (
proveedor ...,
t2_sk int not null references dbo.t2(sk)
)

Ahora puedes actualizar producto y unidad_medida en t2 sin necesidad de
actualizar t3.


AMB

"Paco" wrote:

> Hola a todos.
> Antes de nada decir que soy algo novato en sql y estoy haciendo mis primeros
> pinitos.
> Tengo una bbdd en sql 2005
>
> Tengo las siguientes tablas
> T1 : Unidades de medida
> UnidadMedida - k
>
> T2: Unidades de medida producto
> Producto - k
> UnidadMedida - k
>
> T3: Precios proveedor
> Proveedor - k
> Producto - k
> UnidadMedida -k
>
> Tengo una relacion T1-T2 por el campo unidad de medida. Update on cascada
>
> Tengo una relacion T2-T3 por los campos producto y unidad de medida. Update
> no acction porque no me deja sql por otras relaciones.
>
> He creado el siguiente trigger en T2 para mantener la integridad referencial
>
> CREATE TRIGGER [U_COMUnidadesMedidaProducto_ProductoUM]
> ON [COMUnidadesMedidaProducto]
> FOR UPDATE
> AS
>
> IF NOT UPDATE(Producto) AND NOT UPDATE(UnidadMedida)
> RETURN
>
> declare @actUM varchar(20), @antUM varchar(20)
> SELECT @actUM = UnidadMedida FROM Inserted
> SELECT @antUM = UnidadMedida FROM Deleted
>
> declare @actProducto varchar(20), @antProducto varchar(20)
> SELECT @actProducto = Producto FROM Inserted
> SELECT @antProducto = Producto FROM Deleted
>
> UPDATE PreciosProductosProveedor
> SET Producto = @actProducto, UnidadMedida = @actUM
> FROM Inserted
> WHERE PreciosProductosProveedor.Producto = @antProducto AND
> PreciosProductosProveedor.UnidadMedida = @antUM
>
> El trigger me funciona sólo para el primer producto que se modifica en T2.
> Alguien me podría ayudar y decirme porque solo funciona para el primer
> registro que modifica y como podría hacer para que me funcionase para todos
> los registros.
>
> Gracias a todos de antemano.
>
>
Respuesta Responder a este mensaje
#4 Alejandro Mesa
08/09/2006 - 14:09 | Informe spam
Paco,

Entendistes muy bien lo que quize decir. Quizas soy yo quien no se explica
correctamente.

Ahora, si en vez de hacer la relacion entre las [t2] y [t3] por medio de las
columnas [producto] y [unidadmedida], lo haces por la nueva columna identity,
ya no tendras que actualizar nada en [t3] cuando algo cambie en [t2].


AMB


"Paco" wrote:

Gracias por la respuesta.
Me ha costado entender lo que me queriais decir pero al final creo que lo he
entendido. He solucionado de este modo, pero no sé si es muy correcto.

He añadido un campo identity en t2 para vincular los registros INSERTED y
DELETED y el trigger me ha quedado de esta forma.

ALTER TRIGGER [dbo].[U_COMUnidadesMedidaProducto_ProductoUM]
ON [dbo].[COMUnidadesMedidaProducto]
FOR UPDATE
AS

IF NOT UPDATE(Producto) AND NOT UPDATE(UnidadMedida)
RETURN


UPDATE COMPreciosProductosProveedor
SET Producto = I.Producto, UnidadMedida = I.UnidadMedida
FROM Inserted AS I
JOIN Deleted AS D ON D.ClaveId = I.ClaveId
WHERE COMPreciosProductosProveedor.Producto = D.Producto AND
COMPreciosProductosProveedor.UnidadMedida = D.UnidadMedida

"Alejandro Mesa" escribió:

> Paco,
>
> Ademas de lo dicho por Antonio, quiero agregar que los triggers son
> disparados por cada sentencia involucrada y no por cada fila afectada. Por
> eso es que debes contemplar la participacion de multiples filas cuando
> programamos un trigger.
>
> Lo otro que quiero comentar es que se hace muy pero muy dificil hacer este
> tipo de cosas cuando lo que estamos modificando es la clave primaria, puesto
> que la vinculacion entre las tablas "deleted" e "inserted" se pierde. No hay
> manera de vincular los nuevos valores de la clave primaria con los viejos
> valores, por lo que no sabemos cual de las filas en la tabla inserted
> corresponde con que fila de la tabla t3. Para estos casos se hace muy
> practico el uso de una clave subrrogada, la cual no se permite modificar y
> que es usada por la integridad referencial.
>
> create table dbo.t2 (
> sk int not null identity unique,
> producto ...,
> unidad_medida ...
> )
>
> create table dbo.t3 (
> proveedor ...,
> t2_sk int not null references dbo.t2(sk)
> )
>
> Ahora puedes actualizar producto y unidad_medida en t2 sin necesidad de
> actualizar t3.
>
>
> AMB
>
> "Paco" wrote:
>
> > Hola a todos.
> > Antes de nada decir que soy algo novato en sql y estoy haciendo mis primeros
> > pinitos.
> > Tengo una bbdd en sql 2005
> >
> > Tengo las siguientes tablas
> > T1 : Unidades de medida
> > UnidadMedida - k
> >
> > T2: Unidades de medida producto
> > Producto - k
> > UnidadMedida - k
> >
> > T3: Precios proveedor
> > Proveedor - k
> > Producto - k
> > UnidadMedida -k
> >
> > Tengo una relacion T1-T2 por el campo unidad de medida. Update on cascada
> >
> > Tengo una relacion T2-T3 por los campos producto y unidad de medida. Update
> > no acction porque no me deja sql por otras relaciones.
> >
> > He creado el siguiente trigger en T2 para mantener la integridad referencial
> >
> > CREATE TRIGGER [U_COMUnidadesMedidaProducto_ProductoUM]
> > ON [COMUnidadesMedidaProducto]
> > FOR UPDATE
> > AS
> >
> > IF NOT UPDATE(Producto) AND NOT UPDATE(UnidadMedida)
> > RETURN
> >
> > declare @actUM varchar(20), @antUM varchar(20)
> > SELECT @actUM = UnidadMedida FROM Inserted
> > SELECT @antUM = UnidadMedida FROM Deleted
> >
> > declare @actProducto varchar(20), @antProducto varchar(20)
> > SELECT @actProducto = Producto FROM Inserted
> > SELECT @antProducto = Producto FROM Deleted
> >
> > UPDATE PreciosProductosProveedor
> > SET Producto = @actProducto, UnidadMedida = @actUM
> > FROM Inserted
> > WHERE PreciosProductosProveedor.Producto = @antProducto AND
> > PreciosProductosProveedor.UnidadMedida = @antUM
> >
> > El trigger me funciona sólo para el primer producto que se modifica en T2.
> > Alguien me podría ayudar y decirme porque solo funciona para el primer
> > registro que modifica y como podría hacer para que me funcionase para todos
> > los registros.
> >
> > Gracias a todos de antemano.
> >
> >
Respuesta Responder a este mensaje
#5 Paco
08/09/2006 - 15:43 | Informe spam
Gracias de nuevo por la pronta respuesta.
Te habias explicado perfectamente, lo que pasa es que tengo más tablas y
relaciones, además de la forma de introducir los datos en la capa de
presentacion, y me es más facil hacerlo así como te he dicho. Lo único que
quería constatar es que no hubiese ningún problema de otra indole que yo no
alcanzase a ver. Como he comentado antes no tengo demasiada experiencia con
sql server.

gracias de nuevo por tu atención

"Alejandro Mesa" escribió:

Paco,

Entendistes muy bien lo que quize decir. Quizas soy yo quien no se explica
correctamente.

Ahora, si en vez de hacer la relacion entre las [t2] y [t3] por medio de las
columnas [producto] y [unidadmedida], lo haces por la nueva columna identity,
ya no tendras que actualizar nada en [t3] cuando algo cambie en [t2].


AMB


"Paco" wrote:

> Gracias por la respuesta.
> Me ha costado entender lo que me queriais decir pero al final creo que lo he
> entendido. He solucionado de este modo, pero no sé si es muy correcto.
>
> He añadido un campo identity en t2 para vincular los registros INSERTED y
> DELETED y el trigger me ha quedado de esta forma.
>
> ALTER TRIGGER [dbo].[U_COMUnidadesMedidaProducto_ProductoUM]
> ON [dbo].[COMUnidadesMedidaProducto]
> FOR UPDATE
> AS
>
> IF NOT UPDATE(Producto) AND NOT UPDATE(UnidadMedida)
> RETURN
>
>
> UPDATE COMPreciosProductosProveedor
> SET Producto = I.Producto, UnidadMedida = I.UnidadMedida
> FROM Inserted AS I
> JOIN Deleted AS D ON D.ClaveId = I.ClaveId
> WHERE COMPreciosProductosProveedor.Producto = D.Producto AND
> COMPreciosProductosProveedor.UnidadMedida = D.UnidadMedida
>
> "Alejandro Mesa" escribió:
>
> > Paco,
> >
> > Ademas de lo dicho por Antonio, quiero agregar que los triggers son
> > disparados por cada sentencia involucrada y no por cada fila afectada. Por
> > eso es que debes contemplar la participacion de multiples filas cuando
> > programamos un trigger.
> >
> > Lo otro que quiero comentar es que se hace muy pero muy dificil hacer este
> > tipo de cosas cuando lo que estamos modificando es la clave primaria, puesto
> > que la vinculacion entre las tablas "deleted" e "inserted" se pierde. No hay
> > manera de vincular los nuevos valores de la clave primaria con los viejos
> > valores, por lo que no sabemos cual de las filas en la tabla inserted
> > corresponde con que fila de la tabla t3. Para estos casos se hace muy
> > practico el uso de una clave subrrogada, la cual no se permite modificar y
> > que es usada por la integridad referencial.
> >
> > create table dbo.t2 (
> > sk int not null identity unique,
> > producto ...,
> > unidad_medida ...
> > )
> >
> > create table dbo.t3 (
> > proveedor ...,
> > t2_sk int not null references dbo.t2(sk)
> > )
> >
> > Ahora puedes actualizar producto y unidad_medida en t2 sin necesidad de
> > actualizar t3.
> >
> >
> > AMB
> >
> > "Paco" wrote:
> >
> > > Hola a todos.
> > > Antes de nada decir que soy algo novato en sql y estoy haciendo mis primeros
> > > pinitos.
> > > Tengo una bbdd en sql 2005
> > >
> > > Tengo las siguientes tablas
> > > T1 : Unidades de medida
> > > UnidadMedida - k
> > >
> > > T2: Unidades de medida producto
> > > Producto - k
> > > UnidadMedida - k
> > >
> > > T3: Precios proveedor
> > > Proveedor - k
> > > Producto - k
> > > UnidadMedida -k
> > >
> > > Tengo una relacion T1-T2 por el campo unidad de medida. Update on cascada
> > >
> > > Tengo una relacion T2-T3 por los campos producto y unidad de medida. Update
> > > no acction porque no me deja sql por otras relaciones.
> > >
> > > He creado el siguiente trigger en T2 para mantener la integridad referencial
> > >
> > > CREATE TRIGGER [U_COMUnidadesMedidaProducto_ProductoUM]
> > > ON [COMUnidadesMedidaProducto]
> > > FOR UPDATE
> > > AS
> > >
> > > IF NOT UPDATE(Producto) AND NOT UPDATE(UnidadMedida)
> > > RETURN
> > >
> > > declare @actUM varchar(20), @antUM varchar(20)
> > > SELECT @actUM = UnidadMedida FROM Inserted
> > > SELECT @antUM = UnidadMedida FROM Deleted
> > >
> > > declare @actProducto varchar(20), @antProducto varchar(20)
> > > SELECT @actProducto = Producto FROM Inserted
> > > SELECT @antProducto = Producto FROM Deleted
> > >
> > > UPDATE PreciosProductosProveedor
> > > SET Producto = @actProducto, UnidadMedida = @actUM
> > > FROM Inserted
> > > WHERE PreciosProductosProveedor.Producto = @antProducto AND
> > > PreciosProductosProveedor.UnidadMedida = @antUM
> > >
> > > El trigger me funciona sólo para el primer producto que se modifica en T2.
> > > Alguien me podría ayudar y decirme porque solo funciona para el primer
> > > registro que modifica y como podría hacer para que me funcionase para todos
> > > los registros.
> > >
> > > Gracias a todos de antemano.
> > >
> > >
email Siga el debate Respuesta Responder a este mensaje
Ads by Google
Help Hacer una preguntaRespuesta Tengo una respuesta
Search Busqueda sugerida