Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Principal > SQL
Registrarse FAQ Miembros Calendario Guía de estilo Temas de Hoy

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 10-11-2010
Avatar de tgsistemas
tgsistemas tgsistemas is offline
Miembro
 
Registrado: dic 2003
Ubicación: Barcelona
Posts: 149
Poder: 21
tgsistemas Va por buen camino
Trigger para eliminar en cascada master/detail

Hola a tod@s :

trabajo con D7, tengo una bbdd en SQL 2005 Express con unas tablas Master / Detail y he creado el siguiente trigger en la tabla Master (AREC01E) para que al eliminar un registro, elimine en cascada los registros de la tabla Detail (AREC02E) que le corresponden.

El trigger es :

Código SQL [-]
ALTER TRIGGER [dbo].[del_areae] ON [dbo].[AREC01E] for delete as
declare @CDGOTEMP integer
begin
  SELECT @CDGOTEMP = CDGO FROM DELETED
  DELETE FROM AREC02E WHERE CDGOCAB = @CDGOTEMP
end

el trigger funciona correctamente si la tabla detail (AREC02E) tiene un único registro pero el problema viene cuando la tabla detail tiene más de un registro y produce el
Código:
"error información de columna clave insuficiente o incorrecta, demasiadas filas afectadas por la actualización"
qué es lo que estoy haciendo mal ???

muchas gracias a tod@s por la ayuda
__________________
Toni | blog
Responder Con Cita
  #2  
Antiguo 10-11-2010
Avatar de Al González
[Al González] Al González is offline
In .pas since 1991
 
Registrado: may 2003
Posts: 5.604
Poder: 29
Al González Es un diamante en brutoAl González Es un diamante en brutoAl González Es un diamante en brutoAl González Es un diamante en bruto
Hola Toni.

No necesitas un disparador para la eliminación en cascada.

Basta con que la restricción de llave foránea de la tabla detalle esté creada con la opción "On Delete Cascade".

http://www.mssqlcity.com/Articles/Ge...onstraints.htm

Saludos.
Responder Con Cita
  #3  
Antiguo 10-11-2010
Avatar de BlueSteel
[BlueSteel] BlueSteel is offline
Miembro Premium
 
Registrado: may 2003
Ubicación: Concepción - Chile
Posts: 2.310
Poder: 23
BlueSteel Va por buen camino
Cita:
Empezado por Al González Ver Mensaje
Hola Toni.

No necesitas un disparador para la eliminación en cascada.

Basta con que la restricción de llave foránea de la tabla detalle esté creada con la opción "On Delete Cascade".

http://www.mssqlcity.com/Articles/Ge...onstraints.htm

Saludos.

No sabia de esto... muy buen aporte... y yo que me daba el trabajo de borrar todo...
__________________
BlueSteel
Responder Con Cita
  #4  
Antiguo 10-11-2010
Avatar de duilioisola
[duilioisola] duilioisola is offline
Miembro Premium
 
Registrado: ago 2007
Ubicación: Barcelona, España
Posts: 1.734
Poder: 20
duilioisola Es un diamante en brutoduilioisola Es un diamante en brutoduilioisola Es un diamante en bruto
Es verdad lo de la llave foranea, pero no resuelve todos los casos.
El error que tiene tu trigger parece ser que es que debes utilizar un bucle para seleccionar cada línea y borrarla.

No conozco SQL Server, pero supongo que debe ser algo así:

Código SQL [-]
ALTER TRIGGER [dbo].[del_areae] ON [dbo].[AREC01E] for delete as
declare @CDGOTEMP integer
begin
  FOR SELECT @CDGOTEMP = CDGO FROM DELETED
  BEGIN
     DELETE FROM AREC02E WHERE CDGOCAB = @CDGOTEMP
  END
end

Resolver este problema te servirá por ejemplo cuando quieras guardar registros borrados en un log o hacer algunos recálculos sobre terceras tablas por cada registro borrado.
Responder Con Cita
  #5  
Antiguo 11-11-2010
Avatar de BlueSteel
[BlueSteel] BlueSteel is offline
Miembro Premium
 
Registrado: may 2003
Ubicación: Concepción - Chile
Posts: 2.310
Poder: 23
BlueSteel Va por buen camino
Cita:
Empezado por duilioisola Ver Mensaje
Es verdad lo de la llave foranea, pero no resuelve todos los casos.
El error que tiene tu trigger parece ser que es que debes utilizar un bucle para seleccionar cada línea y borrarla.
Hace un tiempo yo lo hacia con cursores.... deja buscar un ejemplo y lo dejo...

Salu2
__________________
BlueSteel

Última edición por BlueSteel fecha: 11-11-2010 a las 00:15:20.
Responder Con Cita
  #6  
Antiguo 11-11-2010
Avatar de BlueSteel
[BlueSteel] BlueSteel is offline
Miembro Premium
 
Registrado: may 2003
Ubicación: Concepción - Chile
Posts: 2.310
Poder: 23
BlueSteel Va por buen camino
Aqui te dejo el ejemplo
Código SQL [-]
Create TRIGGER [Producto_Update]
   ON  [dbo].[Producto]
   FOR Update
AS 
BEGIN
    SET NOCOUNT ON;

    -- Sentencia que cuenta cuantos registros se eliminaran..
    -- Si son más de uno.. da error
/*    if ((Select Count(*) From Deleted) > 1) 
    Begin
         RaisError(' Quiere Eliminar mas de uno',16,1)
         Rollback Transaction 
    End
    
    -- Sentencia que verifica que el dato no este en otra tabla
    -- de lo contrario no elimina...
    if Exists(Select 1 From DVenta
              Where DVenta.Pro_Codigo in
                    (Select Deleted.Pro_Codigo From Deleted))
    Begin
         RaisError(' No se puede eliminar',16,1)
         Rollback Transaction 
    End


    if Exists(Select 1 From Venta, DVenta, updated
              Where Venta.Vta_Numero = DVenta.Vta_Numero
                And DVenta.Pro_Codigo = Updated.Pro_Codigo)
    Begin
         RaisError(' Existe',16,1)
         Rollback Transaction 
    End
*/
   -- Declaración de Cursores
    
    Declare @Codigo Int,
            @Descripcion Varchar(10)

    Declare  Cur_Prueba Cursor
    For Select Pro_Codigo, Pro_Detalle For Update

    Open Cur_Prueba

    Fetch Next From Cur_Prueba Into @Codigo, @Descripcion

    While @@Fetch_Status = 0
    Begin
         /*
         */
         Fetch Next From Cur_Prueba Into @Codigo, @Descripcion
    End

    Close Cur_Prueba
    DealLocate Cur_Prueba    
    
END

bueno, esto es un ejemplo que vi en un curso de SQL.... aunque aqui utiliza el Update... tendrias que cambiar por Delete....

Salu2
__________________
BlueSteel
Responder Con Cita
  #7  
Antiguo 11-11-2010
ASAPLTDA ASAPLTDA is offline
Miembro
 
Registrado: jun 2003
Ubicación: COLOMBIA-CALI
Posts: 639
Poder: 21
ASAPLTDA Va por buen camino
Smile Comentario

DELETE FROM AREC02E WHERE CDGOCAB = @CDGOTEMP
Esta instruccion borrara todos los registros de la trabla sin usar cursor. No sera que tienes un trigger asociados a la tabla AREC02E?
Responder Con Cita
  #8  
Antiguo 15-11-2010
Avatar de tgsistemas
tgsistemas tgsistemas is offline
Miembro
 
Registrado: dic 2003
Ubicación: Barcelona
Posts: 149
Poder: 21
tgsistemas Va por buen camino
uffff me había centrado en otro proceso del programa que fallaba y no he estado atento a vuestras respuestas... os pido disculpas a todos!!!!.

Esta aplicación la desarrollé hace tiempo en D7 y SQL2000 conectando con BDE, ahora estaba haciendo una nueva versión del programa utilizando ADO contra SQL2005 Express por cuestiones de costes para los clientes

Ese trigger funcionaba correctamente en SQL2000 tal y como está, aunque para evitar sorpresas creo que me instalaré un SQL2000 para hacer pruebas y estar seguro.

Al Gonzalez.... he mirado muy por encima la info que me indicas y voy a estudiarla a fondo ahora que tengo más tiempo. Muchas Gracias

Duiliosola.... no soy un experto con SQL pero ese trigger funcionaba correctamente en SQL2000. De todas formas lo voy a comprobar

BlueSteel... gracias por el ejemplo, lo voy a tener en cuenta

ASAPLTDA..... la tabla AREC02E (detail) no tiene ningún trigger.

Gracias a todos por las respuestas, os pido disculpas de nuevo por no contestar antes y si alguien ve dónde puede estar el error o qué estoy haciendo mal... que no dude en decirlo!!!!
__________________
Toni | blog
Responder Con Cita
  #9  
Antiguo 17-01-2011
Avatar de tgsistemas
tgsistemas tgsistemas is offline
Miembro
 
Registrado: dic 2003
Ubicación: Barcelona
Posts: 149
Poder: 21
tgsistemas Va por buen camino
Thumbs up solucionado

bueno tras más de dos meses en producción puedo asegurar que la opción que propuso Al Gonzalez funciona a las mil maravillas.... muchas gracias!!!!
__________________
Toni | blog
Responder Con Cita
Respuesta



Normas de Publicación
no Puedes crear nuevos temas
no Puedes responder a temas
no Puedes adjuntar archivos
no Puedes editar tus mensajes

El código vB está habilitado
Las caritas están habilitado
Código [IMG] está habilitado
Código HTML está deshabilitado
Saltar a Foro

Temas Similares
Tema Autor Foro Respuestas Último mensaje
DBLookupComboBoxs Master/Detail o Detail/Master yusnerqui OOP 5 29-07-2005 18:40:20
eliminar en cascada con intebase squenda Firebird e Interbase 1 06-08-2004 08:26:36
master/detail, imprimiendo master en cada hoja acalderonr Impresión 4 29-11-2003 14:46:07
interbase:¿como crear un master-detail-detail? ElSanto24 Firebird e Interbase 2 22-10-2003 10:24:45
Master/Detail/Detail/Detail/etc... hgiacobone Tablas planas 2 24-07-2003 17:20:31


La franja horaria es GMT +2. Ahora son las 11:20:02.


Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi
Copyright 1996-2007 Club Delphi