2009-08-10 3 views
0

У меня есть две таблицы A и B с ссылкой на столбец в B с ограничениями внешнего ключа. Теперь я пытаюсь добавить больше столбцов и ограничений в таблицу A, отбросив таблицу A и снова создав таблицу A новыми столбцами. SQL Server Mgmt Studio предоставляет опцию «Drop and Create» для этого, когда я изменяю инструкцию create table, чтобы добавить больше столбцов.Разрешение внешних ограничений между связанными таблицами

Выполнение инструкций выдает сообщение об ошибке, на которое А ссылается на ограничение внешнего ключа. Чтобы исправить это, мне пришлось удалить ограничение внешнего ключа из таблицы A, а затем выполнить команду «drop and create». В моем случае я мог бы сделать это, сбросив одно ограничение. Я не могу сделать то же самое с набором таблиц, перекрестно ссылающихся друг на друга. Это должно быть обычным явлением для большинства разработчиков SQL, и мне интересно, есть ли способ справиться с этой ситуацией, не удаляя и не воссоздавая сеть ограничений между таблицами.

Цените свои комментарии!

ПРИМЕР SQL: Текущая таблица:

CREATE TABLE [dbo].[TableA](
    [PhotoId] [bigint] IDENTITY(1,1) NOT NULL, 
    [PhotoTypeId] [bigint] NOT NULL, 
    [PhotoDescription] [nvarchar](max) NULL, 
    [LastModifiedBy] [bigint] NOT NULL, 
    [LastModifiedDate] [datetime] NOT NULL, 
CONSTRAINT [PK_TableA] PRIMARY KEY CLUSTERED 
(
    [PhotoId] 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 

SET ANSI_PADDING OFF 
GO 

ALTER TABLE [dbo].[TableA] WITH NOCHECK ADD CONSTRAINT [FK_TableA_TableAType] FOREIGN KEY([PhotoTypeId]) 
REFERENCES [dbo].[TableAType] ([PhotoTypeId]) 
GO 

ALTER TABLE [dbo].[TableA] NOCHECK CONSTRAINT [FK_TableA_TableAType] 
GO 

ALTER TABLE [dbo].[TableA] WITH NOCHECK ADD CONSTRAINT [FK_TableA_TableB1] FOREIGN KEY([LastModifiedBy]) 
REFERENCES [dbo].[TableB] ([UserId]) 
GO 

ALTER TABLE [dbo].[TableA] NOCHECK CONSTRAINT [FK_TableA_TableB1] 
GO 

ALTER TABLE [dbo].[TableA] ADD CONSTRAINT [DF_TableA_IsDeleted] DEFAULT ((0)) FOR [IsDeleted] 
GO 

ожидается таблица

CREATE TABLE [dbo].[TableA](
    [PhotoId] [bigint] IDENTITY(1,1) NOT NULL, 
    [PhotoTypeId] [bigint] NOT NULL, 
    [PhotoDescription] [nvarchar](max) NULL, 
    ***[PhotoWidth] [int] NOT NULL, 
    [PhotoHeight] [int] NOT NULL,*** 
    [LastModifiedBy] [bigint] NOT NULL, 
    [LastModifiedDate] [datetime] NOT NULL, 
CONSTRAINT [PK_TableA] PRIMARY KEY CLUSTERED 
(
    [PhotoId] 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 

SET ANSI_PADDING OFF 
GO 

ALTER TABLE [dbo].[TableA] WITH NOCHECK ADD CONSTRAINT [FK_TableA_TableAType] FOREIGN KEY([PhotoTypeId]) 
REFERENCES [dbo].[TableAType] ([PhotoTypeId]) 
GO 

ALTER TABLE [dbo].[TableA] NOCHECK CONSTRAINT [FK_TableA_TableAType] 
GO 

ALTER TABLE [dbo].[TableA] WITH NOCHECK ADD CONSTRAINT [FK_TableA_TableB1] FOREIGN KEY([LastModifiedBy]) 
REFERENCES [dbo].[TableB] ([UserId]) 
GO 

ALTER TABLE [dbo].[TableA] NOCHECK CONSTRAINT [FK_TableA_TableB1] 
GO 

ALTER TABLE [dbo].[TableA] ADD CONSTRAINT [DF_TableA_IsDeleted] DEFAULT ((0)) FOR [IsDeleted] 
GO 

ответ

2

Решение: Не использовать конструктор таблиц в Management Studio. Шутки в сторону. Не. Это реликт более десятилетия назад, и он не очень хорошо знает SQL. (Зайдите на connect.microsoft.com, и вы найдете много, много ошибок и предложений, поданных против него.)

Вы можете (и должны) добавлять столбцы и ограничения с помощью SQL без отбрасывания и воссоздания таблицы, копирования данных , воссоздавая ограничения и т.д.

ALTER TABLE A ADD myNewColumn int; 
ALTER TABLE A ADD CONSTRAINT ... 

Если у вас есть особое положение вы не знаете SQL, пожалуйста дает CREATE TABLE/INDEX/Constraint заявление и объяснить, что вам нужно сделать.

Добавлено: В примере, который вы добавили к своему вопросу, вот одна строка SQL. Я добавил значения по умолчанию только потому, что они вам понадобятся, если ваша таблица уже содержит данные при добавлении столбцов, которые не являются NULL.

ALTER TABLE dbo.TableA ADD PhotoWidth INT NOT NULL DEFAULT 640, PhotoHeight INT NOT NULL DEFAULT 480; 
+0

Я всегда использую дизайнер, и это на самом деле работает довольно хорошо. Это также намного быстрее для большинства случаев. – Kevin

+0

спасибо steve. добавлен образец кода SQL. – pencilslate

+0

@Kevin: «Быстрее для большинства случаев», чем что? Дизайнер генерирует SQL и/или хранимые вызовы proc, которые любой может написать (но часто не должен). Как вызовы SQL и proc дизайнера могут быть быстрее, чем SQL-запросы разработчика и proc? –

0

Нет, вам нужно отказаться от ограничений. Но хорошие новости! ™ - это то, что вы можете использовать select из таблиц information_schema (или вашего эквивалента rdbms) до сгенерировать операторы alter table drop constraint.

Ах, но Стив Касс более внимательно прочитал ваш вопрос, чем я. Просто добавить колонны, не отбрасывая стол, с alter table add column ....

+0

Спасибо! Является ли чтение внимательно стоящим? :) –

1

Я никогда не сталкивался с этой проблемой. Когда я изменяю таблицу, я использую конструктор для добавления столбцов, сохранения, и он работает как волшебство ... Он предупреждает меня о других таблицах, ссылающихся на этот, но я нажимаю «ОК», и моя таблица изменена!

Во всяком случае, вы можете удалить ссылочные ограничения на таблицах, выполнив:

ALTER TABLE [name] NOCHECK CONSTRAINT ALL 

и позволяют им:

ALTER TABLE [name] CHECK CONSTRAINT ALL 

Если вы изменяете много таблиц, вы могут:

До изменения:

EXEC sp_msforeachtable 'ALTER TABLE ? NOCHECK CONSTRAINT ALL' 

После модификации:

EXEC sp_msforeachtable 'ALTER TABLE ? CHECK CONSTRAINT ALL' 
+0

ограничение NOCHECK не работает. Я добавил образец sql к моему сообщению. – pencilslate

+0

Для записи, если вы выполняете NOCHECK, тогда ПРОВЕРЬТЕ, как вы предлагаете, ограничения проверки и внешнего ключа не будут перепроверены в данных таблицы, и они останутся «ненадежными» и не будут использоваться оптимизатором. Если вы хотите перепроверить данные, вы должны сказать CHECK CHECK, верьте или нет! ALTER TABLE [имя] ПРОВЕРИТЬ ПРОВЕРИТЬ КОНСТРУИРОВАТЬ ВСЕ –

+0

NOCHECK по-прежнему не позволяет мне изменять таблицу. похоже, его проще выполнять оператор alter для столбцов отдельно, чем отбрасывать и создавать таблицу. опять же, я считаю, что мне нужно отказаться и создать, если изменяемые столбцы связаны с ограничениями. оцените объяснение. благодаря! – pencilslate

Смежные вопросы