"Попередити збереження змін, які потребують повторного створення таблиці", негативні ефекти


255

Преамбула

Я сьогодні модифікував стовпчик у SQL Server 2008, змінивши тип даних з типу валюти (18,0) на (19,2).

У мене виникла помилка "Внесені вами зміни вимагають відхилення та повторного створення наступних таблиць" від SQL Server.

Перш ніж шукати відповіді, будь ласка, прочитайте наступне:

Я вже знаю, що є параметр в Інструментах ► Опції ► Дизайнер ► Дизайнери таблиць і баз даних ► Зніміть прапорець "Запобігати збереженню змін, які потребують відновлення таблиці". Запобігайте збереженню змін, які потребують повторного створення таблиці за п'ять клацань ... тому не відповідайте з цим!

Актуальне питання

Моє актуальне питання полягає в чомусь іншому:

Чи є якісь негативні наслідки / можливі недоліки цього?

Чи насправді таблиця опускається та відтворюється автоматично, коли це поле не встановлено?

Якщо так, то чи є копія таблиці стовідсотковою реплікою вихідної таблиці?


65
Інструменти> Параметри> Дизайнер ... це те, що я шукав! Дякую!
nrod

1
Також зверніть увагу на stackoverflow.com/questions/9870968 / ...
pylover

2
А якщо ви працюєте з MS SQL Server 2014 -> Додаткові елементи> Опції> Дизайнер З верхнього меню.
Вітята

Відповіді:


89

Таблиця випадає та відтворюється лише в тих випадках, коли це єдиний спосіб програмування студії управління SQL Server, щоб знати, як це зробити.

Безумовно, є випадки, коли це робитиметься, коли цього не потрібно, але також будуть випадки, коли зміни, внесені в Studio Studio, не будуть випадатимуть і не створюватимуться заново, оскільки цього не потрібно.

Проблема полягає в тому, що перерахування всіх випадків та визначення того, на яку сторону лінії вони потрапляють, буде досить втомливим.

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


5
Хоча я дійсно гарна відповідь, я вважаю, що вона не дає відповідей на всі питання, порушені ОП, і ці питання насправді цікавлять мене. Зокрема, чи є якісь негативні наслідки / можливі недоліки цього? і якщо так, чи копія таблиці є 100% точною реплікою вихідної таблиці? . Чи є у вас інформація щодо цих питань?
tfrascaroli

252

Інструменти -> Параметри -> Вузол дизайнерів -> Зніміть прапорець " Запобігти збереження змін, які потребують відтворення таблиці ".


12

Довідка - Якщо вимкнути цю опцію, ви можете уникнути повторного створення таблиці, а також може призвести до втрати змін. Наприклад, припустимо, що ви ввімкнули функцію відстеження змін у SQL Server 2008 для відстеження змін у таблиці. Виконуючи операцію, яка спричиняє повторне створення таблиці, ви отримуєте повідомлення про помилку, яке згадується в розділі "Симптоми". Однак якщо вимкнути цю опцію, існуюча інформація відстеження змін буде видалена, коли таблиця буде створена заново. Тому Microsoft рекомендує не займатися цією проблемою, вимкнувши цю опцію.


11

SQL Server опускає та відтворює таблиці, лише якщо:

  • Додати новий стовпець
  • Змініть налаштування Дозволити нулі для стовпця
  • Змініть порядок стовпців у таблиці
  • Змінення типу даних стовпців

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


8
Ваш список не є вичерпним. IDENTITYНаприклад, додайте / видаліть властивість у стовпці.
Аарон Бертран

2
Додавання нового стовпця до кінця полів, який є NULLABLE, не потребує перебудови таблиці.
PseudoToad

2

Так, від цього є негативні наслідки:

Якщо ви скриптуєте зміну, заблоковану цим прапором, ви отримуєте щось на зразок сценарію нижче (все, що я перетворюю стовпчик ідентифікатора в Контакті в стовпчик "Ідентичність", але таблиця має залежності). Зверніть увагу на потенційні помилки, які можуть виникнути під час виконання наступного:

  1. Навіть microsoft попереджає, що це може призвести до втрати даних (цей коментар генерується автоматично)!
  2. протягом періоду часу іноземні ключі не виконуються.
  3. якщо ви вручну запускаєте це в ssms і 'EXEC (' INSERT INTO 'не спрацьовує), і ви дозволяєте запускати наступні оператори (що вони роблять за замовчуванням, оскільки вони розділені на' go '), тоді ви будете вставляти 0 рядків, а потім відміняти старий стіл.
  4. якщо це велика таблиця, час роботи вставки може бути великим, а транзакція містить блокування модифікації схеми, тому блокує багато речей.

-

/* 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
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.