none
Error de: "podrían producirse ciclos o múltiples rutas en cascada. Especifique ON DELETE NO ACTION o UPDATE NO ACTION" RRS feed

  • Pregunta

  • Hola:

    Tengo claro que el error dice que NO me deja activar el UPDATE CASCADE, pero lo que pasa es que no entiendo la razón. Tengo 3 tablas sencillas relacionadas de esta forma:

    Tabla CD => Campo CD: Valores posibles del campo CD (PrimaryKey)

    Tabla FR => Campo FR: Valores posibles del campo FR (PrimaryKey)

                       Campo CD: foreignkey con UPDATE CASCADE a la tabla CD.

                               Cuando 'cambie' el valor del campo CD en la tabla CD, este campo se actualizará automáticamente.

    Tabla PN => Campo PN + Campo CD (PrimaryKey)

                       Campo CD: foreignkey con UPDATE CASCADE a la tabla CD.

                               Cuando 'cambie' el valor del campo CD de la tabla CD, este campo se actualizará automáticamente.

                       Campo FR: foreignkey con la tabla FR... pero si pongo UPDATE CASCADE me da el error indicado.

                               Simplemente quiero que cuando 'cambie' el valor del campo FR de la tabla FR, este campo se actualice.

    No consigo ver el 'bucle' que se genera en las relaciones. ¿alguna explicación / pista?

    Pongo el código para crear las tablas/relaciones.

    CREATE TABLE [PRUEBAS].[CD](	[CD] [int] NOT NULL, 
     CONSTRAINT [PK_CD] PRIMARY KEY CLUSTERED (	[CD] ASC ) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
    ) ON [PRIMARY]
    GO
    
    CREATE TABLE [PRUEBAS].[FR](	[FR] [int] NOT NULL,	[CD] [int] NOT NULL,
     CONSTRAINT [PK_FR] PRIMARY KEY CLUSTERED (	[FR] ASC) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
    ) ON [PRIMARY]
    GO
    
    ALTER TABLE [PRUEBAS].[FR]  WITH CHECK ADD  CONSTRAINT [FK_FR_CD] FOREIGN KEY([CD])
    REFERENCES [PRUEBAS].[CD] ([CD])
    ON UPDATE CASCADE
    GO
    
    ALTER TABLE [PRUEBAS].[FR] CHECK CONSTRAINT [FK_FR_CD]
    GO
    
    CREATE TABLE [PRUEBAS].[PN](	[PN] [int] NOT NULL,	[CD] [int] NOT NULL,	[FR] [int] NOT NULL,
     CONSTRAINT [PK_PN] PRIMARY KEY CLUSTERED (	[PN] ASC,	[CD] ASC ) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
    ) ON [PRIMARY]
    GO
    
    ALTER TABLE [PRUEBAS].[PN]  WITH CHECK ADD  CONSTRAINT [FK_PN_CD] FOREIGN KEY([CD])
    REFERENCES [PRUEBAS].[CD] ([CD])
    ON UPDATE CASCADE
    GO
    
    ALTER TABLE [PRUEBAS].[PN] CHECK CONSTRAINT [FK_PN_CD]
    GO
    
    ALTER TABLE [PRUEBAS].[PN]  WITH CHECK ADD  CONSTRAINT [FK_PN_FR] FOREIGN KEY([FR])
    REFERENCES [PRUEBAS].[FR] ([FR])
    -- ON UPDATE CASCADE <========== ESTE UPDATE CASCADE ES EL PROBLEMATICO.
    GO
    
    ALTER TABLE [PRUEBAS].[PN] CHECK CONSTRAINT [FK_PN_FR]
    GO
    
    
    

    Gracias.

    jueves, 18 de julio de 2019 9:29

Todas las respuestas

  • Deleted
    jueves, 18 de julio de 2019 10:38
  • No consigo ver el 'bucle' que se genera en las relaciones. ¿alguna explicación / pista?

    No es un bucle, es un "doble borrado".

    Cuando borras de CD se tiene que borrar de FR, y se tiene que borrar de PN. Pero al borrar de PN, tambien se tiene que borrar de FR. El resultado es que se tiene que borrar "dos veces" de FR. SQL Server no tiene la inteligencia necesaria para resolver este doble borrado, y lo que hace es arrojar un error para no permitirtelo.

    jueves, 18 de julio de 2019 10:59
  • Hola:

    El mensaje de error lo tengo claro "For example, the tree of cascading referential actions must only have one path to a particular table on the cascading referential actions tree." pero no veo ni el cíclico ni el path duplicado en mi caso:

    No me deja poner la relación (path3) entre PN y FR para el campo FR. Veamos los 'arboles' creados por las relaciones.

    Path1: Tabla CD vs tabla FR (campo CD). Si cambio CD.CD, me cambia en FR.CD

    Path2: Tabla CD vs tabla PN (campo CD). Si cambio CD.CD, me cambia PN.CD

    Path3: Tabla FR vs tabla PN (campo FR). Si cambio FR.FR, me cambia PN.FR

    ¿porque esta relación que usa otro campo que NO se utiliza en ninguna otra relación, entra en conflicto con las otras? Tampoco coincide con otra relación entre FR y PN, es la única entre las dos tablas.

    Tampoco veo nada cíclico, en ningún caso se mezclan tablas, campos... sigo sin ver el error.

    Un saludo

    jueves, 18 de julio de 2019 11:26
  • Cierto, pero yo estoy usando UPDATE CASCADE únicamente, no uso el DELETE CASCADE en ningún momento.

    Si cambio tu explicación por UPDATE me quedo igual :-(

    Si actualizo CD, se tiene que actualizar el campo CD de FR y PN.

    Pero actualizar el campo CD de PN no debería afectar para nada a la table FR, es update de un campo en concreto, no delete de todo el registro.

    Un saludo


    jueves, 18 de julio de 2019 11:44
  • Sí, perdona, es un UPDATE y no un DELETE, pero se aplica la misma explicación. No es un "doble borrado" sino una "doble actualizacion". Da igual que sean distintos campos, SQL Server no tiene la "inteligencia" necesaria para distinguir este matiz. El mero hecho de que la misma tabla pueda potencialmente recibir dos updates es suficiente para que rechace ese CASCADE.
    jueves, 18 de julio de 2019 14:46
  • Hola:

    Está claro que SqlServer no lo acepta, pero para mí es un error (y para mi grave porque me fastidia todo lo que tenia pensado). Si SqlServer hace lo que tiene que hacer, en ningún momento debería haber una doble actualización.

    Modifico FR.FR  => Actualiza PN.FR (y no tiene que hacer nada más)

    Modifico CD.CD => Actualiza FR.CD y PN.CD (y no tiene que hacer nada más)

    La relación entre PN y FR se basa en OTRO CAMPO. Según lo que comentas, ¿una modificación de un registro con una relación en cascada se ejecuta aunque NO modifiques el campo involucrado?

    Me parece, aparte de muy poco eficiente, un error de concepto :-/

    ¿Alguien lo podría probar con otro motor de base de datos, a ver si sucede lo mismo? (editado: en MS Access lo acepta y lo ejecuta perfectamente)

    Un saludo


    • Editado LG DES viernes, 19 de julio de 2019 6:22 MS Access
    viernes, 19 de julio de 2019 6:15
  • Codigo limpio para poder probar con otros motores de bd.

    CREATE TABLE [CD](	[CD] [int] NOT NULL,  CONSTRAINT [PK_CD] PRIMARY KEY CLUSTERED (	[CD] ASC ) ) 
    GO
    
    CREATE TABLE [FR](	[FR] [int] NOT NULL,	[CD] [int] NOT NULL, CONSTRAINT [PK_FR] PRIMARY KEY CLUSTERED (	[FR] ASC) ) 
    GO
    
    ALTER TABLE [FR]  WITH CHECK ADD  CONSTRAINT [FK_FR_CD] FOREIGN KEY([CD]) REFERENCES [CD] ([CD]) ON UPDATE CASCADE
    GO
    
    ALTER TABLE [FR] CHECK CONSTRAINT [FK_FR_CD]
    GO
    
    CREATE TABLE [PN](	[PN] [int] NOT NULL,	[CD] [int] NOT NULL,	[FR] [int] NOT NULL, CONSTRAINT [PK_PN] PRIMARY KEY CLUSTERED (	[PN] ASC,	[CD] ASC ) )
    GO
    
    ALTER TABLE [PN]  WITH CHECK ADD  CONSTRAINT [FK_PN_CD] FOREIGN KEY([CD]) REFERENCES [CD] ([CD]) ON UPDATE CASCADE
    GO
    
    ALTER TABLE [PN] CHECK CONSTRAINT [FK_PN_CD]
    GO
    
    ALTER TABLE [PN]  WITH CHECK ADD  CONSTRAINT [FK_PN_FR] FOREIGN KEY([FR]) REFERENCES [FR] ([FR])
    -- ON UPDATE CASCADE <========== ESTE UPDATE CASCADE ES EL PROBLEMATICO.
    GO
    
    ALTER TABLE [PN] CHECK CONSTRAINT [FK_PN_FR]
    GO

    Gracias

    viernes, 19 de julio de 2019 7:01