#sql #sql-server #tsql #sql-server-2008 #foreign-keys
#sql #sql-сервер #tsql #sql-server-2008 #внешние ключи
Вопрос:
Мне нужно добавить новый внешний ключ в мою таблицу с именем starList
. В настоящее время он не имеет отношения внешнего ключа к вызываемой таблице planetList
.
Итак, я выполнил эту команду:
ALTER TABLE [dbo].[starList] WITH CHECK
ADD CONSTRAINT [FK_starList_planetList]
FOREIGN KEY([planetId]) REFERENCES [dbo].[planetList] ([planetId])
ON UPDATE CASCADE
ON DELETE CASCADE
GO
Но я получаю эту ошибку:
Оператор ALTER TABLE конфликтовал с ограничением ВНЕШНЕГО КЛЮЧА «FK_starList_planetList».
Конфликт произошел в базе данных «astro101», таблица «dbo.planetList», столбец «planetID».
Я не уверен, что это значит.
Я попытался просмотреть свои таблицы на SQL Server, но я не вижу ничего плохого.
Кто-нибудь может помочь мне выяснить, что означает ошибка?
Спасибо!
Моя starList
таблица выглядит следующим образом:
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[starList]
(
[starID] [nvarchar](50) NOT NULL,
[galaxyID] [uniqueidentifier] NOT NULL,
[starTitle] [nvarchar](3000) NULL,
[planetID] [uniqueidentifier] NULL,
CONSTRAINT [PK_StarList]
PRIMARY KEY CLUSTERED ([starID] ASC)
WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF,
IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON,
ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
GO
ALTER TABLE [dbo].[starList] WITH CHECK
ADD CONSTRAINT [FK_starList_galaxyList]
FOREIGN KEY([galaxyID]) REFERENCES [dbo].[galaxyList] ([galaxyID])
ON UPDATE CASCADE
ON DELETE CASCADE
GO
ALTER TABLE [dbo].[starList] CHECK CONSTRAINT [FK_starList_galaxyList]
GO
И planetList
таблица такая:
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[planetList]
(
[planetID] [uniqueidentifier] NOT NULL,
[planetText] [nvarchar](max) NULL,
PRIMARY KEY CLUSTERED ([planetID] ASC)
WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF,
IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON,
ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
GO
Комментарии:
1. На мой взгляд, эта ошибка не является особенно неопределенной. Это говорит вам, что по крайней мере одна существующая строка приведет к сбою ограничения внешнего ключа, поэтому его нельзя создать.
2. Если вы запустите
SELECT sl.planetId FROM dbo.starList sl LEFT JOIN dbo.planetlist pl ON sl.planetId = pl.planetId WHERE pl.planetId IS NULL;
, вы получите строки, которые завершатся ошибкойCONSTRAINT
.3. В качестве дополнительного примечания SQL Server 2008 полностью не поддерживается более года, и вам следует как можно скорее просмотреть пути обновления.
4. @Larnu о, вау, это имеет смысл! Я никогда этого не знал. Я запустил этот запрос и нашел кучу значений planetID внутри моей таблицы starList, которые не существуют внутри таблицы planetList. Я удалю и повторно запущу. Как вы думаете, значения NULL имеют значение? Поскольку столбец planetId в starList по умолчанию равен NULL.
5.
NULL
значения игнорируются для ограничений внешнего ключа, @SkyeBoniwell .
Ответ №1:
Вам нужно проверить свои данные в обоих столбцах.
В столбце таблицы внешних ключей есть значение, связанное с которым значение не существует в таблице первичных ключей.
У вас есть данные в starlist.planetid, которые не соответствуют planetlist.planetid.
Оба они должны быть одинаковыми со значениями values. Было бы лучше обрезать их, а затем попытаться создать ограничение.
Короче говоря, имеет место нарушение правил ссылочной целостности.
Если это так, не забудьте создать внешний ключ перед заполнением таблиц.
Комментарии:
1. Спасибо, дайте мне посмотреть и убедиться
2. Вы можете просто обновить: update tbl set col=null; или удалить и перечитывать столбец; alter table удалить столбец x; alter table добавить столбец x ;
3. О, хорошо, вот так: ОБНОВИТЕ список звезд, УСТАНОВИТЕ planetID = NULL, ГДЕ planetID ОТСУТСТВУЕТ…
4. Усеките весь столбец, а затем добавьте ограничение. Поэтому нет условия where.