“防止需要重新创建表的保存更改”负面影响

时间:2012-08-03 19:55:46

标签: sql-server sql-server-2008 database-design sql-server-2005

序言

我今天在SQL Server 2008中修改了一个列,将数据类型从货币(18,0)更改为(19,2)。

我收到错误“您所做的更改需要从SQL Server中删除并重新创建以下表”。

在您争先恐后地回答之前,请阅读以下内容:

  

我已经知道工具►选项►设计器►表格和数据库设计师►中的选项取消选中“防止保存需要重新创建表格的更改”。   Prevent saving changes that require table re-creation in five clicks   ......所以回答这个问题!

实际问题

我的实际问题是其他内容,如下所示:

这样做有任何负面影响/可能的缺点吗?

当取消选中此框时,表格是否会被实际删除并自动重新创建?

如果是,表格是否复制了源表的100%完全复制品?

5 个答案:

答案 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列,但该表具有依赖关系)。 请注意以下运行时可能发生的潜在错误:

  1. 即便是微软警告说这可能会导致数据丢失(该评论是自动生成的)!
  2. 一段时间内,不强制执行外键。
  3. 如果你在ssms中手动运行它并且'EXEC('INSERT INTO'失败,你让以下语句运行(它们默认执行,因为它们被'go'拆分)然后你将插入0行,然后放下旧桌子。
  4. 如果这是一个大表,插入的运行时可能很大,并且事务持有架构修改锁,因此阻止许多事情。
  5. -

    /* 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