Ngăn chặn lưu các thay đổi yêu cầu bảng được tạo lại hiệu ứng tiêu cực


255

Lời nói đầu

Tôi đã sửa đổi một cột trong SQL Server 2008 ngày hôm nay, thay đổi kiểu dữ liệu từ một cái gì đó như tiền tệ (18,0) thành (19,2).

Tôi đã gặp lỗi "Những thay đổi bạn đã thực hiện yêu cầu bỏ các bảng sau đây và tạo lại" từ SQL Server.

Trước khi bạn tranh giành để trả lời, xin vui lòng đọc phần sau:

Tôi đã biết có tùy chọn trong Công cụ ► Tùy chọn ► Nhà thiết kế ► Nhà thiết kế bảng và cơ sở dữ liệu ► Bỏ chọn hộp "Ngăn chặn lưu thay đổi yêu cầu tạo lại bảng." Ngăn chặn lưu các thay đổi yêu cầu tạo lại bảng trong năm lần nhấp ... vậy đừng trả lời với điều đó!

Câu hỏi thực tế

Câu hỏi thực tế của tôi là cho một cái gì đó khác, như sau:

Có bất kỳ tác động tiêu cực / nhược điểm có thể có của việc này không?

Bảng có thực sự bị rơi và được tạo lại tự động khi hộp này không được chọn không?

Nếu vậy, bảng có sao chép chính xác 100% của bảng nguồn không?


65
Công cụ> Tùy chọn> Nhà thiết kế ... đó là tôi đang tìm kiếm! Cảm ơn!
nrod


2
Và nếu bạn ở với MS SQL Server 2014 -> Extras> Tùy chọn> Trình thiết kế Từ menu trên cùng.
Vityata

Câu trả lời:


89

Bảng chỉ bị hủy và được tạo lại trong trường hợp đó là cách duy nhất SQL Server của Management Studio được lập trình để biết cách thực hiện.

Chắc chắn sẽ có những trường hợp nó sẽ làm điều đó khi không cần thiết, nhưng cũng sẽ có những trường hợp các chỉnh sửa bạn thực hiện trong Management Studio sẽ không bỏ và tạo lại vì không cần phải chỉnh sửa.

Vấn đề là việc liệt kê tất cả các trường hợp và xác định phía nào của dòng họ rơi vào sẽ khá tẻ nhạt.

Đây là lý do tại sao tôi thích sử dụng ALTER TABLEtrong cửa sổ truy vấn, thay vì các nhà thiết kế trực quan che giấu những gì họ đang làm (và hoàn toàn có lỗi) - Tôi biết chính xác điều gì sẽ xảy ra và tôi có thể chuẩn bị cho các trường hợp khả năng duy nhất là để thả và tạo lại bảng (một số ít hơn số lần SSMS sẽ làm điều đó với bạn).


5
Mặc dù câu trả lời thực sự tốt, tôi cảm thấy nó không cung cấp câu trả lời cho tất cả các câu hỏi được đặt ra bởi OP và thực sự những câu hỏi đó là những câu hỏi tôi quan tâm. Cụ thể Có bất kỳ tác động tiêu cực / nhược điểm có thể có của việc này không? nếu vậy, bảng có sao chép chính xác 100% của bảng nguồn không? . Bạn có bất kỳ thông tin liên quan đến những câu hỏi?
tfrascaroli

252

Công cụ -> Tùy chọn -> Nút Nhà thiết kế -> Bỏ chọn " Ngăn chặn lưu thay đổi yêu cầu giải trí bảng ".


12

Tham khảo - Tắt tùy chọn này có thể giúp bạn tránh tạo lại bảng, nó cũng có thể dẫn đến thay đổi bị mất. Ví dụ: giả sử bạn kích hoạt tính năng Theo dõi thay đổi trong SQL Server 2008 để theo dõi các thay đổi đối với bảng. Khi bạn thực hiện thao tác khiến bảng được tạo lại, bạn sẽ nhận được thông báo lỗi được đề cập trong phần "Triệu chứng". Tuy nhiên, nếu bạn tắt tùy chọn này, thông tin theo dõi thay đổi hiện tại sẽ bị xóa khi bảng được tạo lại. Do đó, Microsoft khuyên bạn không nên khắc phục sự cố này bằng cách tắt tùy chọn.


11

SQL Server loại bỏ và tạo lại các bảng chỉ khi bạn:

  • Thêm một cột mới
  • Thay đổi cài đặt Cho phép Nulls cho một cột
  • Thay đổi thứ tự cột trong bảng
  • Thay đổi kiểu dữ liệu cột

Sử dụng ALTER sẽ an toàn hơn, vì trong trường hợp siêu dữ liệu bị mất trong khi bạn tạo lại bảng, dữ liệu của bạn sẽ bị mất.


8
Danh sách của bạn không đầy đủ. Thêm / xóa IDENTITYtài sản trên một cột, ví dụ.
Aaron Bertrand

2
Thêm một cột mới vào cuối các trường là NULLABLE không yêu cầu xây dựng lại bảng.
PseudoToad

2

Vâng, có những tác động tiêu cực từ điều này:

Nếu bạn kịch bản thay đổi bị chặn bởi cờ này, bạn sẽ nhận được một cái gì đó giống như tập lệnh bên dưới (tất cả tôi đang biến cột ID trong Liên hệ thành cột IDENTITY được đánh số tự động, nhưng bảng có phụ thuộc). Lưu ý các lỗi tiềm ẩn có thể xảy ra trong khi sau đây đang chạy:

  1. Ngay cả microsoft cũng cảnh báo rằng điều này có thể gây mất dữ liệu (nhận xét đó được tạo tự động)!
  2. trong một khoảng thời gian, khóa ngoại không được thực thi.
  3. nếu bạn chạy thủ công trong ssms và 'EXEC (' INSERT INTO 'không thành công và bạn để các câu lệnh sau chạy (theo mặc định, chúng được chia theo' go ') thì bạn sẽ chèn 0 hàng, sau đó thả cái bàn cũ.
  4. nếu đây là một bảng lớn, thời gian chạy của chèn có thể lớn và giao dịch đang giữ một khóa sửa đổi lược đồ, do đó, chặn nhiều thứ.

-

/* 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
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.