解决连接表中的外部约束

时间:2009-08-10 02:44:54

标签: sql-server sql-server-2008

我有两个表A和B,其中A引用了B中具有外键约束的列。现在,我试图通过删除表A并使用新列再次创建表A来向表A添加更多列和约束。 SQL Server Mgmt Studio提供“删除和创建”选项来执行此操作,我在其中更改create table语句以添加更多列。

执行语句会抛出一个错误,指出A由外键约束引用。为了解决这个问题,我不得不从表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

3 个答案:

答案 0 :(得分:2)

解决方案:不要在Management Studio中使用表设计器。认真。别。它是十多年前的遗物,它不太了解SQL。 (查看connect.microsoft.com,你会发现很多很多错误和建议。)

您可以(并且应该)使用SQL添加列和约束,而无需删除和重新创建表,复制数据,重新创建约束等。

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

如果您遇到特殊情况,您不知道SQL for,请提供CREATE TABLE / INDEX / CONSTRAINT语句并说明您需要做什么。

补充:对于您添加到问题中的示例,这是一行SQL。我添加默认值只是因为如果你的表在添加列时已包含数据,那么你将需要它们,这些列是非空的。

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

答案 1 :(得分:1)

我从未遇到过这个问题。当我修改一个表时,我使用Designer来添加列,保存,它就像魔术一样...它警告我引用这个的其他表,但我按“确定”,我的表被修改了!

无论如何,您可以通过执行以下操作来删除表上的引用约束:

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'

答案 2 :(得分:0)

不,你必须放弃约束。但Good News!™是您可以使用information_schema表中的select(或您的rdbms等效表)来生成 alter table drop constraint语句。

啊,但史蒂夫卡斯比我更仔细地读你的问题。只需添加列,而不删除表格alter table add column ....