Pregunta

Tengo una base de datos Microsoft SQL con 2 tablas: perros y gatos

.

"perro" tabla tiene una columna de clave principal llamado "alimento", que se relaciona con una columna llamada "comida", así en la tabla de "gato", que actúa como la clave externa.

La relación entre las tablas tiene un conjunto de reglas "en la supresión en cascada", por lo que cuando se borra una fila de la tabla "perro", las filas de la tabla relveant "gato" debería suprimirse también.

Pero las filas de la tabla "gato" se deje neta borra, se quedan. Yo uso el gestor de base de datos Microsoft SQL para eliminar la fila en la tabla "perro".

¿Alguna idea de por qué sucede esto? Qué necesito para utilizar un comando especial sql delete para eliminar una fila de esta manera?

// editar

el guión de las tablas es:

USE [VELES]
GO
/****** Object:  Table [dbo].[Periods]    Script Date: 01/18/2011 14:52:19 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[Periods](
    [PeriodID] [int] IDENTITY(1,1) NOT FOR REPLICATION NOT NULL,
    [PeriodName] [nvarchar](50) COLLATE Hebrew_CS_AS NULL,
    [PeriodStartDate] [smalldatetime] NOT NULL,
    [PeriodEndDate] [smalldatetime] NOT NULL,
 CONSTRAINT [PK_Periods] PRIMARY KEY CLUSTERED 
(
    [PeriodID] ASC
)WITH (IGNORE_DUP_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY]


USE [VELES]
GO
/****** Object:  Table [dbo].[Exams]    Script Date: 01/18/2011 14:55:37 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_PADDING ON
GO
CREATE TABLE [dbo].[Exams](
    [ExamID] [int] IDENTITY(1,1) NOT NULL,
    [ExamUserID] [char](7) COLLATE Hebrew_CS_AS NOT NULL,
    [ExamBase] [tinyint] NOT NULL,
    [ExamUserTimesAccessed] [tinyint] NULL,
    [ExamMaxTimesToOpen] [tinyint] NOT NULL,
    [ExamUserLastTimeOpened] [datetime] NULL,
    [ExamUserLastTimeFinished] [datetime] NULL,
    [ExamTimeToFinish] [int] NOT NULL,
    [ExamPassGrade] [int] NOT NULL,
    [ExamPeriod] [int] NOT NULL,
    [ExamUserRank] [tinyint] NULL,
 CONSTRAINT [PK_Exams] PRIMARY KEY CLUSTERED 
(
    [ExamID] ASC
)WITH (IGNORE_DUP_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY]

GO
SET ANSI_PADDING OFF
GO
USE [VELES]
GO
ALTER TABLE [dbo].[Exams]  WITH CHECK ADD  CONSTRAINT [FK_Exams_Bases] FOREIGN KEY([ExamBase])
REFERENCES [dbo].[Bases] ([BaseID])
ON UPDATE CASCADE
ON DELETE CASCADE
GO
ALTER TABLE [dbo].[Exams]  WITH NOCHECK ADD  CONSTRAINT [FK_Exams_Periods] FOREIGN KEY([ExamPeriod])
REFERENCES [dbo].[Periods] ([PeriodID])
ON UPDATE CASCADE
ON DELETE CASCADE
GO
ALTER TABLE [dbo].[Exams]  WITH NOCHECK ADD  CONSTRAINT [FK_Exams_Users] FOREIGN KEY([ExamUserID])
REFERENCES [dbo].[Users] ([UserID])
ON UPDATE CASCADE
ON DELETE CASCADE
NOT FOR REPLICATION 
GO
ALTER TABLE [dbo].[Exams] CHECK CONSTRAINT [FK_Exams_Users]
GO
ALTER TABLE [dbo].[Exams]  WITH CHECK ADD  CONSTRAINT [UserRanks_Exams_FK1] FOREIGN KEY([ExamUserRank])
REFERENCES [dbo].[UserRanks] ([RankID])
ON UPDATE CASCADE
ON DELETE CASCADE
¿Fue útil?

Solución

He resuelto el problema.

En la ventana de relación, no era una opción llamada Enforce Foreign Key Constraint, que fue establecido en "No". Me puse a "Sí" y ahora la fila eliminación funciona bien.

Otros consejos

Se puede mostrar su estructura de tabla más concretamente? Se sonar como usted tiene la PK / FK al revés.

La eliminación de la parte FK (niño) no hace nada al registro PK (padre). Sólo cuando se eliminan los registros PK lo hace en cascada a los registros secundarios que enlazan con ella.

¿Está seguro el food columna en dog es la clave primaria de dog? Si usted tiene una tabla llamada food, entonces es food columna debe ser la clave primaria de food y una clave externa de dog (y cat también). Luego, con deleciones on delete cascade en food causarán las filas correspondientes en dog y cat que se eliminarán.

Para las personas que utilizan SQL Server Management Studio:

he visto absolutamente casos en los que la interfaz de usuario ha conseguido fuera de sincronización con la base de datos, incluso si se actualiza la lista de teclas o se abre una nueva instancia.

En mi caso tengo una Order que tiene elementos secundarios DiscountedItem.

La manera de comprobar si las cosas están fuera de sincronía es hacer clic derecho sobre FK_DiscountedItem_Order y seleccione Script Key as CREATE To Clipboard y luego examinar lo que se obtiene:

debe obtener algo como esto:

ALTER TABLE [dbo].[DiscountedItem]  WITH NOCHECK ADD  CONSTRAINT    [FK_DiscountedItem_Order] FOREIGN KEY([OrderId])
REFERENCES [dbo].[Order] ([OrderId])
ON DELETE CASCADE
GO

ALTER TABLE [dbo].[DiscountedItem] CHECK CONSTRAINT [FK_DiscountedItem_Order]
GO

¿Dónde se puede ver claramente DELETE CASCADE.

Si usted consigue algo como lo siguiente, entonces la regla de cascada no es realmente activa a pesar de lo que diga la interfaz de usuario:

ALTER TABLE [dbo].[DiscountedItem]  WITH CHECK ADD  CONSTRAINT [FK_DiscountedItem_Order] FOREIGN KEY([OrderId])
REFERENCES [dbo].[Order] ([OrderId])
GO

Me acaba de eliminar que (tenía que tener que borrarlo dos veces) y la reconstruí para obtener el SQL correcto.

Es posible que tenga que ejecutar algo como esto para comprobar si hay 'huérfanos' filas secundarias:

select * from DiscountedItem where DiscountedItem.orderid not in (select orderid from [order])

Y a continuación, si es seguro hacerlo:

delete from DiscountedItem where DiscountedItem.orderid not in (select orderid from [order])

¿Por qué ha ocurrido esto?

solo añadido la restricción e inmediatamente consiguió un error de clave externa porque tenía filas huérfanos. Algo después se confundió y pensó en cascada estaba habilitado.

Así que antes de la creación de una nueva restricción en la interfaz de usuario recomiendo que compruebe siempre primero para las filas huérfanos. Usted tendrá que eliminar todos modos, si es que existen.

Si la tabla de gato es la clave para la clave externa, a continuación, suprimir una fila de perro no elimina una fila de gato, más bien que funcionaría al revés.

Este costuras funcionar muy bien.

delete from Periods where PeriodID = 1

eliminará una fila de puntos y todas las filas de los exámenes que tienen ExamPeriod = 1

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top