我有两个表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
答案 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 ....