Msgstr "Предотвратить сохранение изменений, требующих повторной сборки таблицы".

Преамбула

Я изменил колонку в SQL Server 2008 сегодня, изменив тип данных с чего-то вроде валюты (18,0) до (19,2).

Я получил сообщение об ошибке "Выполненные вами изменения требуют, чтобы следующие таблицы были удалены и повторно созданы" из SQL Server.

Прежде чем вы начнете отвечать, прочитайте следующее:

Я уже знаю, что есть опция в Инструменты ► Параметры ► Дизайнер ► Дизайнеры таблиц и баз данных ► Снимите флажок "Предотвратите сохранение изменений, требующих повторного создания таблицы". Запретить сохранение изменений, требующих повторного создания таблицы за пять кликов... так не отвечайте с этим!

Актуальный вопрос

Мой реальный вопрос - это что-то еще:

Есть ли какие-либо негативные последствия/возможные недостатки этого?

Действительно ли таблица удаляется и воссоздается автоматически, когда этот флажок не установлен?

Если да, то скопирует ли таблица 100% точную копию исходной таблицы?

Ответ 1

Таблица удаляется и воссоздается только в тех случаях, когда только SQL Server Management Studio запрограммирован так, чтобы знать, как это сделать.

Конечно, есть случаи, когда он будет делать это, когда это не нужно, но также будут случаи, когда изменения, внесенные вами в Management Studio, не будут падать и воссоздаваться, потому что это не обязательно.

Проблема в том, что перечисление всех случаев и определение того, на какой стороне линии они попадают, будет довольно утомительным.

Вот почему я люблю использовать ALTER TABLE в окне запроса вместо визуальных дизайнеров, которые скрывают, что они делают (и, откровенно говоря, имеют ошибки) - Я точно знаю, что произойдет, и я могу подготовиться к тем случаям, когда единственной возможностью является сброс и повторная создание таблицы (что немного меньше, чем часто SSMS будет делать это с вами).

Ответ 2

Инструменты → Параметры → Дизайнеры node → Снимите флажок " Предотвратить сохранение изменений, требующих рекреации стола ".

Ответ 3

Ссылка. Отключение этой опции поможет вам избежать повторного создания таблицы, это также может привести к утере изменений. Например, предположим, что вы включили функцию отслеживания изменений в SQL Server 2008 для отслеживания изменений в таблице. Когда вы выполняете операцию, которая заставляет таблицу воссоздаваться, вы получаете сообщение об ошибке, указанное в разделе "Проблема". Однако, если вы отключите этот параметр, существующая информация отслеживания изменений будет удалена при восстановлении таблицы. Поэтому Microsoft рекомендует, чтобы вы не обошли эту проблему, отключив эту опцию.

Ответ 4

SQL Server откатывается и воссоздает таблицы только в том случае, если вы:

  • Добавить новый столбец
  • Измените параметр Allow Nulls для столбца
  • Изменить порядок столбцов в таблице
  • Изменить тип данных столбца

Использование ALTER более безопасно, так как в случае потери метаданных при повторном создании таблицы ваши данные будут потеряны.

Ответ 5

Да, есть негативные последствия от этого:

Если вы script вне изменений, заблокированных этим флагом, вы получите что-то вроде script ниже (все, что я превращаю в столбец ID в Contact в столбец с номером autonumbered IDENTITY, но в таблице есть зависимости). Обратите внимание на потенциальные ошибки, которые могут возникать при выполнении следующего:

  • Даже Microsoft предупреждает, что это может привести к потере данных (этот комментарий автогенерируется)!
  • в течение некоторого периода времени внешние ключи не применяются.
  • если вы вручную запускаете это в ssms, а "EXEC" ( "INSERT INTO" завершается с ошибкой, и вы запускаете следующие операторы (что они делают по умолчанию, поскольку они разделены на "go" ), тогда вы вставляете 0 строк, затем откройте старую таблицу.
  • Если это большая таблица, время выполнения вставки может быть большим, а транзакция удерживает блокировку модификации схемы, поэтому блокирует многие вещи.

-

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