Foros del Web » Programación para mayores de 30 ;) » Bases de Datos General » SQL Server »

SQL server- Transac INSTEAD od update

Estas en el tema de SQL server- Transac INSTEAD od update en el foro de SQL Server en Foros del Web. al compilar el trigger no me bota error. al tratar de actualizar un nombre con un valor vacío, me bota el error esperado, osea hasta ...
  #1 (permalink)  
Antiguo 02/03/2012, 18:33
 
Fecha de Ingreso: marzo-2009
Mensajes: 120
Antigüedad: 15 años, 1 mes
Puntos: 1
SQL server- Transac INSTEAD od update

al compilar el trigger no me bota error.

al tratar de actualizar un nombre con un valor vacío, me bota el error esperado, osea hasta ahí todo bien.

Pero cuando quiero actualizar el nombre con un valor normal , como por ejemplo 'carlos', me bota el siguiente error

"los valores de las filas actualizados no la convierten en única o alteran varias filas"

Debo aclarar que quiero despejar las dudas para fines didácticos, se que puedo usar un AFTER UPDATE y después un rollback, pero deseo saber por que este triger en particular me bota ese mensaje

Muchas gracias por la colaboracion.

acá el ejemplo.


Creación de la tabla, con un ID autoincremental, el cual deber ser único para cada registro

USE [prueba]
GO

/****** Object: Table [dbo].[empleados] Script Date: 03/02/2012 19:25:10 ******/
SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

SET ANSI_PADDING ON
GO

CREATE TABLE [dbo].[empleados](
[id] [int] IDENTITY(1,1) NOT NULL,
[nombre] [varchar](50) NULL,
[apellido] [varchar](50) NULL,
[sueldo] [numeric](18, 0) NULL
) ON [PRIMARY]

GO

SET ANSI_PADDING OFF
GO




y el triger mencionado.


USE prueba;
GO
IF OBJECT_ID ('gatilloup','TR') IS NOT NULL
DROP TRIGGER gatilloup;
GO

CREATE TRIGGER gatilloup ON prueba.dbo.empleados
INSTEAD OF UPDATE
AS

DECLARE @nombre nvarchar(50), @apellido nvarchar(50), @id int;

IF (SELECT nombre FROM inserted) = ''
BEGIN
RAISERROR ('No se puede actualziar a un nombre vacio.', 16, 1);
RETURN
END

ELSE
BEGIN
UPDATE prueba.dbo.empleados
SET nombre = I.nombre,
apellido = I.apellido
FROM prueba.dbo.empleados E, inserted I
WHERE E.id = I.id
RETURN
END


GO

Última edición por samardj; 02/03/2012 a las 18:41
  #2 (permalink)  
Antiguo 05/03/2012, 12:56
Avatar de iislas
Colaborador
 
Fecha de Ingreso: julio-2007
Ubicación: Mexico, D.F.
Mensajes: 6.482
Antigüedad: 16 años, 9 meses
Puntos: 180
Respuesta: SQL server- Transac INSTEAD od update

Primiero, estas asumiendo que en tu tabla inserted hay UN SOLO REGISTRO y esto, no es del todo correcto, cuando se haga una actualizacion masiva.

Segundo, debes de utilizar INNER JOIN para ligar tus tablas y dejar de utilizar codigo antiguo en tu WHERE.
__________________
MCTS Isaias Islas
  #3 (permalink)  
Antiguo 06/03/2012, 10:01
 
Fecha de Ingreso: marzo-2009
Mensajes: 120
Antigüedad: 15 años, 1 mes
Puntos: 1
Respuesta: SQL server- Transac INSTEAD od update

gracias iislas, pero no me has sido de ayuda, no estoy asumiendo que hay un solo registro.

Es que hay un solo registro, siempre habra un solo registro al ejecutar un trigger. y todos sus datos estaran en la tabla inserted,

el WHERE es solo sintaxis, funciona perfectamente igual que el INNER JOIN
  #4 (permalink)  
Antiguo 06/03/2012, 10:35
Avatar de iislas
Colaborador
 
Fecha de Ingreso: julio-2007
Ubicación: Mexico, D.F.
Mensajes: 6.482
Antigüedad: 16 años, 9 meses
Puntos: 180
Respuesta: SQL server- Transac INSTEAD od update

¿Que version-edicion de SQL Server manejas?

¿Que pasa si hay una actualizacion masiva?
__________________
MCTS Isaias Islas
  #5 (permalink)  
Antiguo 06/03/2012, 10:54
 
Fecha de Ingreso: marzo-2009
Mensajes: 120
Antigüedad: 15 años, 1 mes
Puntos: 1
Respuesta: SQL server- Transac INSTEAD od update

si hay una actualización masiva por ejemplo de 100 registros, el trigger se ejecutara 100 veces por registro, no se si estas familiarizado con los triggers, asumo que si porque decidiste responder mi pregunta, siempre habrá un @@indentity referente a la inserción o actualizacion.

mi pregunta fue una y nos desviamos del tema... y esta al principio.
  #6 (permalink)  
Antiguo 06/03/2012, 11:41
Avatar de Libras
Colaborador
 
Fecha de Ingreso: agosto-2006
Ubicación: En la hermosa perla de occidente
Mensajes: 7.412
Antigüedad: 17 años, 8 meses
Puntos: 774
Respuesta: SQL server- Transac INSTEAD od update

el error que te esta marcando


"los valores de las filas actualizados no la convierten en única o alteran varias filas"

indica que en el trigger se esta actualizando mas de un valor

y segun lo que veo el error esta aqui:

Código SQL:
Ver original
  1. UPDATE prueba.dbo.empleados
  2. SET nombre = I.nombre,
  3. apellido = I.apellido
  4. FROM prueba.dbo.empleados E, inserted I
  5. WHERE E.id = I.id

ya que pones que actualice donde empleados se encuentre dentro de inserted yo creo que te faltaria esto:

Código SQL:
Ver original
  1. UPDATE prueba.dbo.empleados
  2. SET nombre = I.nombre,
  3. apellido = I.apellido
  4. FROM prueba.dbo.empleados E, inserted I
  5. WHERE E.id = I.id AND prueba.dbo.empleados.id=I.id
:)
__________________
What does an execution plan say to t-sql query? Go f**k yourself, if you are not happy with me
  #7 (permalink)  
Antiguo 06/03/2012, 11:56
 
Fecha de Ingreso: marzo-2009
Mensajes: 120
Antigüedad: 15 años, 1 mes
Puntos: 1
Respuesta: SQL server- Transac INSTEAD od update

Gracias por responder libras, pero si te das cuenta

E es el alias de prueba.dbo.empleados
I es el alias de Inserted

asi que WHERE E.id = I.id , me deberia referenciar a 1 registro.

igual ya cambie le script para evitar confuciones, pero todavia no me da

Código:
BEGIN
   UPDATE empleados 
   SET empleados.nombre = inserted.nombre,
       empleados.apellido = inserted.apellido
   FROM empleados , inserted 
   WHERE empleados.id_emp = inserted.id_emp
   
END
He hecho otro ejercicio y me funciona perfectamente, en otra DB y otra tabla y es el siguiente

Código:
    BEGIN
		UPDATE ventas SET
		ventas.fk_cliente = inserted.fk_cliente,
		ventas.fk_producto = inserted.fk_producto,
		ventas.fecha = GETDATE()
		FROM
		ventas, inserted
		WHERE ventas.id_ventas = inserted.id_ventas
		
		
	END
El segundo codigo si me pfunciona perfectamente, los dos son INSTEAD OF UPDATE
  #8 (permalink)  
Antiguo 06/03/2012, 12:08
 
Fecha de Ingreso: marzo-2009
Mensajes: 120
Antigüedad: 15 años, 1 mes
Puntos: 1
Respuesta: SQL server- Transac INSTEAD od update

He aqui el error que obtengo.



estoy actualizando desde el management studio, asi que solo actualizo de a 1 registro.

esta porcion de codigo me deberia referenciar ese registro

WHERE empleados.id_emp = inserted.id_emp
  #9 (permalink)  
Antiguo 06/03/2012, 13:10
Avatar de Libras
Colaborador
 
Fecha de Ingreso: agosto-2006
Ubicación: En la hermosa perla de occidente
Mensajes: 7.412
Antigüedad: 17 años, 8 meses
Puntos: 774
Respuesta: SQL server- Transac INSTEAD od update

Probaste con la solucion que te mencione??? ya revisaste que tus id's no se repitan?? puedes checar si haces en tu trigger un:


select * from inserted
select * from deleted

en cualquier parte del codigo y ver realmente cuales son los id's que estas mandando al update :) prueba y comentas.

Saludos!
__________________
What does an execution plan say to t-sql query? Go f**k yourself, if you are not happy with me
  #10 (permalink)  
Antiguo 06/03/2012, 15:28
 
Fecha de Ingreso: marzo-2009
Mensajes: 120
Antigüedad: 15 años, 1 mes
Puntos: 1
Respuesta: SQL server- Transac INSTEAD od update

al tratar de poner 2 veces lo mismo, osea.

WHERE E.id = I.id AND prueba.dbo.empleados.id=I.id, me bota error de enlace


al tratar de consultar la tabla inserted dentro del codigo del triger no ejecuta 'consulta' nada.

he creado un SP para que im prima la variable, y desde el trigger capturo el id de inserted y lo mando al SP pero no ejecuta nada
  #11 (permalink)  
Antiguo 06/03/2012, 15:39
 
Fecha de Ingreso: marzo-2009
Mensajes: 120
Antigüedad: 15 años, 1 mes
Puntos: 1
Respuesta: SQL server- Transac INSTEAD od update

he comprobado el id de otra forma y pongo el codigo

Código PHP:
BEGIN
    SELECT 
@id_ id_emp FROM inserted
        
    RAISERROR 
('id = %d .'161,@id_);
    
    
UPDATE empleados 
    SET empleados
.nombre inserted.nombre,
        
empleados.apellido inserted.apellido
    FROM empleados 
,inserted 
    WHERE empleados
.id_emp = @id_
   
END 
He puesto el raise error para que me bote el dato del id del inserted, y ciertamente me imprime el numero de id que estoy intentando actualizar.
Luego borro el raiseerror y procedo a actualizar algun dato y me sigue botando el error que les imprimi 3 mensajes atras
  #12 (permalink)  
Antiguo 06/03/2012, 16:26
Avatar de Libras
Colaborador
 
Fecha de Ingreso: agosto-2006
Ubicación: En la hermosa perla de occidente
Mensajes: 7.412
Antigüedad: 17 años, 8 meses
Puntos: 774
Respuesta: SQL server- Transac INSTEAD od update

amigo tienes un trigger para hacerlo en un update o en un insert???

CREATE TRIGGER gatilloup ON prueba.dbo.empleados
INSTEAD OF UPDATE

INSTEAD OF UPDATE triggers can be defined on a view or table to replace the standard action of the UPDATE statement. Typically, the INSTEAD OF UPDATE trigger is defined on a view to modify data in one or more base tables.

No necesitas un trigger after insert?? si no te aparece nada en el select * from inserted o select * from deleted entonces algo esta pasando, checate el status de tus triggers con este query:

Código SQL:
Ver original
  1. SELECT trigger_name = sysobjects.name, trigger_owner = USER_NAME(sysobjects.uid),table_schema = s.name, TABLE_NAME = OBJECT_NAME(parent_obj),
  2.   isupdate = OBJECTPROPERTY( id, 'ExecIsUpdateTrigger'), isdelete = OBJECTPROPERTY( id, 'ExecIsDeleteTrigger'),
  3.   isinsert = OBJECTPROPERTY( id, 'ExecIsInsertTrigger'), isafter = OBJECTPROPERTY( id, 'ExecIsAfterTrigger'),
  4.   isinsteadof = OBJECTPROPERTY( id, 'ExecIsInsteadOfTrigger'),
  5.   [disabled] = OBJECTPROPERTY(id, 'ExecIsTriggerDisabled')
  6. FROM sysobjects INNER JOIN sysusers ON sysobjects.uid = sysusers.uid
  7. INNER JOIN sys.TABLES t ON sysobjects.parent_obj = t.object_id
  8. INNER JOIN sys.schemas s ON t.schema_id = s.schema_id
  9. WHERE sysobjects.TYPE = 'TR'

Saludos!
__________________
What does an execution plan say to t-sql query? Go f**k yourself, if you are not happy with me
  #13 (permalink)  
Antiguo 06/03/2012, 21:35
 
Fecha de Ingreso: marzo-2009
Mensajes: 120
Antigüedad: 15 años, 1 mes
Puntos: 1
Respuesta: SQL server- Transac INSTEAD od update

saludos libras, estoy haciendo un triggerINSTEAD OF UPDATE.

Basicamente lo que entiendo es que si hago un triger AFTER UPDATE, ese triger se ejecuta despues de realizar la accion del update, hago las comprobaciones que tenga que hacer, sobre la tabla inserted , y si no cumple algun requisito personal hago un ROLLBACK TRANSACTION, osea deshago el update.

El INSTEAD OF UPDATE, se ejecuta antes de hacer el update en la tabla, y si pasa los requisitos personales, hago el update sobre la tabla, extrayendo los datos de la tabla inserted. (como lo defini en el mensaje anterior)

asi

el nombre de la tabla es inserted para los trigers, insert y update.

en mi caso estoy ejecuntando un INSTEAD OF UPDATE, hago una comprobacion y luego paso a actualizar desde la tabla inserted.

como tambien mostre en el mensaje anterior estoy imprimiendo ese id de la tabla inserted y corresponde al id del registro que estoy actualizando.

lo mas raro de todo es que, como mostre en un mensaje anterior, hice otro ejemplo en otra tabla, y si me hizo el update aplicando el INSTEAD OF UPDATE

he corrido un script para que me muestre los triggers activos en mi db.

USE prueba
GO

SELECT sys.sysobjects.name AS Tabla,sys.triggers.name AS [Trigger], sys.events.type_desc AS Evento,
case when is_disabled = 0
then
'ACTIVADO'
else
'DESACTIVADO'
END As Estado
FROM sys.triggers INNER JOIN
sys.events ON sys.triggers.object_id = sys.events.object_id INNER JOIN
sys.sysobjects ON sys.triggers.parent_id = sys.sysobjects.id
order by sys.sysobjects.name

y solo tengo un trigger UPDATE y es el que estamos discutiendo.

si deseas probarlo, al principio del hilo esta el script de crear tabla, y el de generar el triger para que lo pongas si quieres en tu maquina.

saludos
  #14 (permalink)  
Antiguo 07/03/2012, 09:35
Avatar de Libras
Colaborador
 
Fecha de Ingreso: agosto-2006
Ubicación: En la hermosa perla de occidente
Mensajes: 7.412
Antigüedad: 17 años, 8 meses
Puntos: 774
Respuesta: SQL server- Transac INSTEAD od update

tambien esta la tabla deleted para los triggers de update, porque no en lugar de hacer un update para probar pintas un select donde tienes tu update algo asi:
Código SQL:
Ver original
  1. CREATE TRIGGER gatilloup ON prueba.dbo.empleados
  2. INSTEAD OF UPDATE
  3. AS
  4.  
  5. DECLARE @nombre nvarchar(50), @apellido nvarchar(50), @id INT;
  6.  
  7. IF (SELECT nombre FROM inserted) = ''
  8. BEGIN
  9. RAISERROR ('No se puede actualziar a un nombre vacio.', 16, 1);
  10. RETURN
  11. END
  12.  
  13. ELSE
  14. BEGIN
  15.  
  16. SELECT * FROM prueba.dbo.empleados E, inserted I
  17. WHERE E.id = I.id
  18. RETURN
  19. END

y vez que es lo que regresa realmente el query si te regresa muchos registros, uno, ninguno etc :)

Saludos!
__________________
What does an execution plan say to t-sql query? Go f**k yourself, if you are not happy with me
  #15 (permalink)  
Antiguo 07/03/2012, 10:54
 
Fecha de Ingreso: marzo-2009
Mensajes: 120
Antigüedad: 15 años, 1 mes
Puntos: 1
Respuesta: SQL server- Transac INSTEAD od update

mm hola libras mira he hecho otro ejemplo y me funciona perfectamente.

esto me desconcierta, que el siguiente ejemplo si sirve.

Código HTML:
USE funciones_
GO

IF OBJECT_ID('productos_up','TR') IS NOT NULL
DROP TRIGGER productos_up
GO

CREATE TRIGGER productos_up ON productos
INSTEAD OF UPDATE
AS
BEGIN
	IF (SELECT nombre from inserted) = 'cigarrillo'
	BEGIN
		RAISERROR('No se puede insertar ese producto',16,1)
	END
	
	ELSE
	BEGIN
		UPDATE productos SET
		productos.nombre = inserted.nombre,
		productos.precio = inserted.precio,
		productos.tiene_iva = inserted.tiene_iva
		FROM productos,inserted
		WHERE productos.id_producto =  inserted.id_producto 
	END

END
GO
  #16 (permalink)  
Antiguo 07/03/2012, 13:20
Avatar de Libras
Colaborador
 
Fecha de Ingreso: agosto-2006
Ubicación: En la hermosa perla de occidente
Mensajes: 7.412
Antigüedad: 17 años, 8 meses
Puntos: 774
Respuesta: SQL server- Transac INSTEAD od update

y que te regresa el trigger que te recomende?
__________________
What does an execution plan say to t-sql query? Go f**k yourself, if you are not happy with me
  #17 (permalink)  
Antiguo 07/03/2012, 16:37
 
Fecha de Ingreso: marzo-2009
Mensajes: 120
Antigüedad: 15 años, 1 mes
Puntos: 1
Respuesta: SQL server- Transac INSTEAD od update

wl trugger que em recomendaste no me regresa nada, nunca me ha devuelto datos un trigger, ni siquiera un SELECT 3+4 as suma, entonces la unica forma de comprobar los valores dentro del trigger, por lo menos para mi, es con el raiseerror e imprimir el ID del inserted
  #18 (permalink)  
Antiguo 08/03/2012, 09:25
Avatar de Libras
Colaborador
 
Fecha de Ingreso: agosto-2006
Ubicación: En la hermosa perla de occidente
Mensajes: 7.412
Antigüedad: 17 años, 8 meses
Puntos: 774
Respuesta: SQL server- Transac INSTEAD od update

Como que un trigger no regresa nada? si yo tengo triggers after insert, after update que si les pongo un select * from inserted o select * from deleted me regresan los registros que se estan manejando, si le pongo un select 4+3 me regresa el resultado tambien...si no te regresa nada cuando pones un select * from inserted o un select * from deleted entonces algo esta pasando con tus triggers o con ese trigger :P, ya intentanste borrarlo y crearlo con un nuevo nombre??
__________________
What does an execution plan say to t-sql query? Go f**k yourself, if you are not happy with me

Etiquetas: registro, select, server, sql, tabla, update
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta

SíEste tema le ha gustado a 1 personas




La zona horaria es GMT -6. Ahora son las 13:15.