Frage

Ich habe eine Microsoft SQL-Datenbank mit 2 Tabellen: Hund und Katze

.

„dog“ Tabelle hat einen Primärschlüssel Spalte „Lebensmittel“ genannt, die auf eine Spalte „Lebensmittel“ sowie in der „Katze“ Tabelle genannt verwandt ist, die als Fremdschlüssel wirkt.

Die Beziehung zwischen den Tabellen hat einen „auf Lösch Kaskade“ Regelsatz, so dass, wenn ich eine Reihe von „Hund“ Tabelle löschen, die Relveant Zeilen aus „cat“ Tabelle sollten auch gelöscht werden.

Aber die Zeilen in "cat" Tabelle tun net get gelöscht, sie bleiben. Ich verwende den Microsoft SQL-Datenbank-Manager die Zeile in "dog" Tabelle zu löschen.

Jede Idee, warum dies geschieht? brauche ich einen speziellen Lösch SQL-Befehl verwenden, um eine Zeile in dieser Weise zu löschen?

// edit

das Skript für die Tabellen lautet:

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
War es hilfreich?

Lösung

Ich habe das Problem gelöst.

In der Beziehung Fenstern gibt es eine Option namens Enforce Foreign Key Constraint, die auf „Nein“ gesetzt wurden. Ich stelle es auf „Ja“ und jetzt rudern Löschung gut funktioniert.

Andere Tipps

Können Sie zeigen Sie Ihre Tabellenstruktur konkreter? Es klingt wie Sie den PK / FK der falsche Weg, um sich zu haben.

Löschen des FK Teil (Kind) nichts mit dem PK Rekord tun (Stamm). Nur wenn Sie die PK Datensätze löschen tut es um die untergeordneten Datensätze Kaskade, die auf es.

Sind Sie die Spalte food in dog sicher, dass der Primärschlüssel dog? Wenn Sie eine Tabelle mit dem Namen food haben, dann sollte es die Spalte food der Primärschlüssel food sein und ein Fremdschlüssel von dog (und cat als auch). Dann mit on delete cascade Deletionen auf food die entsprechenden Zeilen auf dog und cat verursacht gelöscht werden.

Für Menschen mit SQL Server Management Studio:

Ich habe absolut Fälle gesehen, wo die Benutzeroberfläche mit dem DB synchron aus gelangt ist, auch wenn es Sie die Schlüssel-Liste aktualisiert oder eine völlig neue Instanz geöffnet.

Für meinen Fall habe ich eine Order die DiscountedItem geordneten Elemente hat.

Die Art und Weise zu überprüfen, ob die Dinge synchron sind out ist auf der rechten Maustaste auf FK_DiscountedItem_Order und wählen Sie Script Key as CREATE To Clipboard und dann untersuchen, was Sie bekommen:

Sie sollte etwas wie diese:

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

Wo man deutlich DELETE CASCADE sehen kann.

Wenn Sie so etwas wie die folgenden bekommen, dann ist die Kaskade Regel ist nicht wirklich aktiv trotz allem, was der UI sagen kann:

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

Ich löschte es nur (musste tatsächlich zweimal löschen) und neu erstellt es die richtige SQL zu bekommen.

Sie müssen möglicherweise etwas laufen für ‚verwaiste‘ untergeordnete Zeilen überprüfen:

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

Und dann, wenn es sicher ist, dies zu tun:

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

Warum ist das passiert?

I nur fügte der Zwang und bekam sofort einen Fremdschlüssel Fehler, weil ich verwaiste Reihen hatte. Etwas dann wurde verwirrt und dachte Kaskade aktiviert wurde.

Also, bevor eine neue Einschränkung in der Benutzeroberfläche mir die Schaffung empfehlen Sie immer zuerst für verwaiste Zeilen zu überprüfen. Sie müssen sie trotzdem löschen, wenn sie vorhanden sind.

Wenn die Katze Tabelle der Schlüssel für den Fremdschlüssel ist, dann eine Reihe von Hund Löscht nicht eine Zeile von Katze zu löschen, vielmehr wäre es um die andere Art und Weise arbeiten.

Diese Nähte gut funktionieren.

delete from Periods where PeriodID = 1

wird eine Reihe von Perioden löschen und alle Zeilen aus Prüfungen, die haben ExamPeriod = 1

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top