序言
我今天在SQL Server 2008中修改了一个列,将数据类型从货币(18,0)更改为(19,2)。
我收到错误“您所做的更改需要从SQL Server中删除并重新创建以下表”。
在您争先恐后地回答之前,请阅读以下内容:
我已经知道工具►选项►设计器►表格和数据库设计师►中的选项取消选中“防止保存需要重新创建表格的更改”。 ......所以不回答这个问题!
实际问题
我的实际问题是其他内容,如下所示:
这样做有任何负面影响/可能的缺点吗?
当取消选中此框时,表格是否会被实际删除并自动重新创建?
如果是,表格是否复制了源表的100%完全复制品?
答案 0 :(得分:248)
工具 - >选项 - >设计者节点 - >取消选中“阻止保存需要使用表格重新设置的更改”。
答案 1 :(得分:86)
只有在SQL Server的Management Studio被编程为知道如何操作的唯一方法的情况下,才会删除并重新创建表。
在某些情况下肯定会在不需要的情况下执行此操作,但在某些情况下,您在Management Studio中进行的编辑将不删除并重新创建,因为它不会不得不。
问题在于列举所有案例并确定他们所在行的哪一方将是相当乏味的。
这就是为什么我喜欢在查询窗口中使用ALTER TABLE
,而不是隐藏他们正在做的事情的视觉设计师(并且坦率地说有错误) - 我确切地知道会发生什么,而我可以为唯一的可能性是丢弃并重新创建表格的情况做准备(这比SSMS对你这样做的频率要少一些)。
答案 2 :(得分:11)
Reference - 关闭此选项可以帮助您避免重新创建表格,但也可能导致更改丢失。例如,假设您在SQL Server 2008中启用“更改跟踪”功能以跟踪对表的更改。当您执行导致重新创建表的操作时,您会收到“症状”部分中提到的错误消息。但是,如果关闭此选项,则在重新创建表时将删除现有的更改跟踪信息。因此,Microsoft建议您不要通过关闭该选项来解决此问题。
答案 3 :(得分:11)
只有在您执行以下操作时,SQL Server才会删除并重新创建表:
使用ALTER更安全,因为在重新创建表时元数据丢失的情况下,您的数据将会丢失。
答案 4 :(得分:1)
是的,这会产生负面影响:
如果您编写了一个被此标志阻止的更改,您将得到类似下面脚本的内容(我将所有内容都将联系人中的ID列转换为自动编号的IDENTITY列,但该表具有依赖关系)。 请注意以下运行时可能发生的潜在错误:
-
/* To prevent any potential data loss issues, you should review this script in detail before running it outside the context of the database designer.*/
BEGIN TRANSACTION
GO
ALTER TABLE raw.Contact
DROP CONSTRAINT fk_Contact_AddressType
GO
ALTER TABLE ref.ContactpointType SET (LOCK_ESCALATION = TABLE)
GO
COMMIT
BEGIN TRANSACTION
GO
ALTER TABLE raw.Contact
DROP CONSTRAINT fk_contact_profile
GO
ALTER TABLE raw.Profile SET (LOCK_ESCALATION = TABLE)
GO
COMMIT
BEGIN TRANSACTION
GO
CREATE TABLE raw.Tmp_Contact
(
ContactID int NOT NULL IDENTITY (1, 1),
ProfileID int NOT NULL,
AddressType char(2) NOT NULL,
ContactText varchar(250) NULL
) ON [PRIMARY]
GO
ALTER TABLE raw.Tmp_Contact SET (LOCK_ESCALATION = TABLE)
GO
SET IDENTITY_INSERT raw.Tmp_Contact ON
GO
IF EXISTS(SELECT * FROM raw.Contact)
EXEC('INSERT INTO raw.Tmp_Contact (ContactID, ProfileID, AddressType, ContactText)
SELECT ContactID, ProfileID, AddressType, ContactText FROM raw.Contact WITH (HOLDLOCK TABLOCKX)')
GO
SET IDENTITY_INSERT raw.Tmp_Contact OFF
GO
ALTER TABLE raw.PostalAddress
DROP CONSTRAINT fk_AddressProfile
GO
ALTER TABLE raw.MarketingFlag
DROP CONSTRAINT fk_marketingflag_contact
GO
ALTER TABLE raw.Phones
DROP CONSTRAINT fk_phones_contact
GO
DROP TABLE raw.Contact
GO
EXECUTE sp_rename N'raw.Tmp_Contact', N'Contact', 'OBJECT'
GO
ALTER TABLE raw.Contact ADD CONSTRAINT
Idx_Contact_1 PRIMARY KEY CLUSTERED
(
ProfileID,
ContactID
)
GO
ALTER TABLE raw.Contact ADD CONSTRAINT
Idx_Contact UNIQUE NONCLUSTERED
(
ProfileID,
ContactID
)
GO
CREATE NONCLUSTERED INDEX idx_Contact_0 ON raw.Contact
(
AddressType
)
GO
ALTER TABLE raw.Contact ADD CONSTRAINT
fk_contact_profile FOREIGN KEY
(
ProfileID
) REFERENCES raw.Profile
(
ProfileID
) ON UPDATE NO ACTION
ON DELETE NO ACTION
GO
ALTER TABLE raw.Contact ADD CONSTRAINT
fk_Contact_AddressType FOREIGN KEY
(
AddressType
) REFERENCES ref.ContactpointType
(
ContactPointTypeCode
) ON UPDATE NO ACTION
ON DELETE NO ACTION
GO
COMMIT
BEGIN TRANSACTION
GO
ALTER TABLE raw.Phones ADD CONSTRAINT
fk_phones_contact FOREIGN KEY
(
ProfileID,
PhoneID
) REFERENCES raw.Contact
(
ProfileID,
ContactID
) ON UPDATE NO ACTION
ON DELETE NO ACTION
GO
ALTER TABLE raw.Phones SET (LOCK_ESCALATION = TABLE)
GO
COMMIT
BEGIN TRANSACTION
GO
ALTER TABLE raw.MarketingFlag ADD CONSTRAINT
fk_marketingflag_contact FOREIGN KEY
(
ProfileID,
ContactID
) REFERENCES raw.Contact
(
ProfileID,
ContactID
) ON UPDATE NO ACTION
ON DELETE NO ACTION
GO
ALTER TABLE raw.MarketingFlag SET (LOCK_ESCALATION = TABLE)
GO
COMMIT
BEGIN TRANSACTION
GO
ALTER TABLE raw.PostalAddress ADD CONSTRAINT
fk_AddressProfile FOREIGN KEY
(
ProfileID,
AddressID
) REFERENCES raw.Contact
(
ProfileID,
ContactID
) ON UPDATE NO ACTION
ON DELETE NO ACTION
GO
ALTER TABLE raw.PostalAddress SET (LOCK_ESCALATION = TABLE)
GO
COMMIT