2013-08-12 23 views
7

Trong công cụ dữ liệu SQL Server Công cụ bạn có tùy chọn triển khai "Chặn triển khai gia tăng nếu mất dữ liệu có thể xảy ra", mà tôi cược là cách tốt nhất để kiểm tra. Cho phép nói rằng chúng tôi có một bảng foo, và một thanh cột mà bây giờ là dư thừa - không có phụ thuộc, khóa ngoài vvvvà chúng tôi đã loại bỏ các tham chiếu đến cột này trong lớp dữ liệu của chúng tôi và các thủ tục được lưu trữ vì nó đơn giản là không đã sử dụng. Nói cách khác, chúng tôi hài lòng rằng việc giảm cột này sẽ không có tác dụng phụ.Mức độ chi tiết của "Chặn triển khai gia tăng nếu mất dữ liệu có thể xảy ra"

Có một vài con ruồi trong thuốc mỡ:

  1. Các cột có dữ liệu trong nó
  2. Cơ sở dữ liệu được công bố để hàng trăm khách hàng phân phối, và nó có thể mất vài tháng cho sự thay đổi để gợn sóng cho tất cả khách hàng

Khi cột được điền, xuất bản sẽ không thành công trừ khi chúng tôi thay đổi tùy chọn "Chặn triển khai gia tăng nếu mất dữ liệu có thể xảy ra". Tuy nhiên, tùy chọn này ở cấp cơ sở dữ liệu, không phải là cấp độ bảng và do tính chất phân tán của khách hàng, chúng tôi phải tắt tùy chọn "mất dữ liệu" trong nhiều tháng trước khi tất cả cơ sở dữ liệu được cập nhật và bật lại một khi tất cả khách hàng đã cập nhật (cơ sở dữ liệu của chúng tôi có số phiên bản do công ty của chúng tôi thiết lập).

Bạn có thể nghĩ chúng ta có thể giải quyết việc này với một kịch bản trước khi triển khai như

if exists (select * from information_schema.columns where table_name = 'foo' and column_name = 'bar') BEGIN 
    alter table foo drop constraint DF_foo_bar 
    alter table foo drop column bar 
END 

Nhưng một lần nữa thất bại này trừ khi chúng tôi lần lượt các "mất dữ liệu có thể xảy ra" tùy chọn tắt.

Tôi chỉ đơn giản quan tâm đến những gì người khác đã làm trong trường hợp này vì tôi muốn có mức độ chi tiết mà hiện tại dường như không thể.

+1

Tôi vừa mới thiết lập tùy chọn đó để False và được biết rằng nó được thực hiện và biết hậu quả. Tôi không biết làm thế nào bạn đang đẩy bản phát hành. Nếu bạn đang tăng dần (áp dụng gói 1, sau đó gói 2, v.v.), bạn có thể tắt nó cho một bản phát hành để thả cột, sau đó bật lại. Nếu chỉ trên một "khi cần thiết" cơ sở, tôi muốn xem xét tắt nó đi và xem DB thay đổi cẩn thận. –

+0

Cảm ơn @PeterSchott. Xây dựng của chúng tôi tạo các dacpacs được tải xuống và áp dụng trên ứng dụng khách, nhưng do bản chất của các bản sửa lỗi và khách hàng (một số khách hàng có thể không sử dụng máy của họ trong mùa đông chẳng hạn và tải bản phát hành mới nhất khi họ bật) cửa sổ để chuyển đổi cài đặt tắt và bật cho một bản phát hành cụ thể hơi khó. Nếu sự đồng thuận là * không * để thiết lập mất dữ liệu, thì đó là điều tôi sẽ phải cân nhắc. Tôi đã luôn luôn nghĩ rằng nó nên được trên. –

+1

Tôi thường đồng ý rằng việc bật tính năng này có thể hữu ích, nhưng đặc biệt trong trường hợp của bạn, bạn có thể muốn xóa nó đi. Nếu bạn hiểu những rủi ro chung thì đó không phải là một vấn đề lớn. Bạn luôn có thể chọn tùy chọn "tạo tập lệnh" để xem lại các thay đổi nếu bạn quan tâm đến các thay đổi khác. Bạn cũng có thể sử dụng tùy chọn để xem dòng lệnh báo cáo thay đổi hoặc một phần của tùy chọn tập lệnh để xem những gì có thể bị ảnh hưởng. –

Trả lời

3

Vì vậy, tôi đã hoàn thành nhiệm vụ này qua các bước sau:

1) Kể từ khi chúng ta sẽ làm cho bảng #Foo, hãy chắc chắn để thả bảng mà trước khi chuyển về phía trước nếu nó tồn tại.
2) Trong tập lệnh triển khai trước: Nếu cột tồn tại, hãy tạo bảng tạm thời #Foo và chọn tất cả các hàng từ Foo vào #Foo.
3) Xóa cột khỏi #Foo
4) Xóa tất cả các hàng trong Foo (hiện tại sẽ không mất dữ liệu vì không có dữ liệu)
5) Trong tập lệnh sau triển khai: Nếu #Foo tồn tại, hãy chọn tất cả hàng từ #Foo vào Foo
6) Thả bảng #Foo

Và mã:

trước triển khai kịch bản

if(Object_ID('TempDB..#Foo') is not null) 
begin 
    drop table #Foo 
end 
if exists (
    select * 
    from sys.columns 
    where Name = 'Bar' 
     and Object_ID = Object_ID('Foo') 
) 
begin  
    select * into #Foo 
    from Foo 

    alter table #Foo drop column Bar 

    -- Now that we've made a complete backup of Foo, we can delete all its data 
    delete Foo 
end 

hậu triển khai kịch bản

if(Object_ID('TempDB..#Foo') is not null) 
begin 
    insert into Foo 
    select * from #Foo 

    drop table #Foo 
end 

Nên biết trước: Tùy thuộc vào môi trường của bạn, nó có thể là khôn ngoan hơn nếu phụ thuộc vào phiên bản chứ không phải cột & tạm thời bảng tồn tại trong điều kiện của bạn

+0

cảm ơn phản hồi. Tôi đã cố gắng này ra và bây giờ có điều này để làm việc theo cách bạn mô tả. Điểm mấu chốt ở đây là bảng phải có 0 hàng trong bảng để nó có thể sửa đổi bảng. Cuối cùng tôi đã không kiểm tra các phiên bản, nhưng sử dụng các khung nhìn lược đồ thông tin trên các cấu trúc bảng để xác định xem có nên thay đổi bất cứ điều gì không. Nice one :) –

+1

Chỉ cần đọc bình luận của bạn dưới đây "Điều này rõ ràng có nghĩa là sao chép dữ liệu ra và có khả năng giảm và tái tạo các phím nước ngoài và kiểm tra ràng buộc vv tùy thuộc vào cấu trúc của bạn" Điều này là đúng - và mặc dù chi tiết đó có thể đi chệch khỏi câu hỏi ban đầu của bạn, tốt để biết cho bất kỳ độc giả trong tương lai. – aaaaaa

3

Kịch bản PreDeployment không hoạt động theo cách bạn đang hy vọng sẽ sử dụng nó vì thứ tự của hoạt động cho SSDT:

  1. Schema So sánh
  2. hệ Script cho sự khác biệt schema
  3. Execute PreDeployment
  4. Tạo kịch bản lệnh được thực hiện
  5. Thực thi Đăng ký.

Vì vậy, tất nhiên, sự khác biệt lược đồ được xác định là một phần của # 2 và SQL thích hợp được tạo ra để thả cột (bao gồm cả kiểm tra để chặn mất dữ liệu), trước khi tập lệnh triển khai thủ công của bạn có thể nhận được bỏ nó đi'.

Nếu bạn có một cái nhìn tại các kịch bản được tạo ra đằng sau hậu trường để phát hiện (và do đó khối) trên mất mát dữ liệu có thể, nó sẽ kiểm tra xem nếu có bất kỳ hàng bằng cách chạy một cái gì đó dọc theo dòng này:

IF EXISTS (select top 1 1 from [dbo].[Table]) RAISERROR ('Rows were detected. The schema update is terminating because data loss might occur.', 16, 127) 

Điều này có nghĩa là sự tồn tại đơn giản của các hàng sẽ ngừng cột bị bỏ. Chúng tôi không tìm thấy cách nào khác ngoài việc xử lý thủ công vấn đề bên ngoài (và trước đó) triển khai SSDT, sử dụng các bước triển khai có điều kiện dựa trên số phiên bản.

Bạn đề cập đến khách hàng được phân phối, điều này ngụ ý bạn có một số loại cơ chế cập nhật/cập nhật tự động. Bạn cũng đề cập đến số phiên bản như một phần của cơ sở dữ liệu - bạn có thể đưa vào triển khai của mình (trước khi lệnh sqlpackage.exe tôi giả sử bạn đang chạy) một tập lệnh SQL thủ công không? Đây là giống như những gì chúng ta làm (chúng ta là trong Powershell, nhưng bạn sẽ có được các ý chính):

IF VersionNumber < 2.8 
BEGIN 
    ALTER TABLE X DROP COLUMN Y 
END 

Disclaimer: không có cách nào là SQL hợp lệ, nó chỉ đơn giản là giả mã để bao hàm một ý tưởng!

+1

Cảm ơn hanzworld đã trả lời. Bình luận của bạn "Chúng tôi không tìm thấy cách nào khác ngoài việc giải quyết vấn đề bên ngoài (và trước đó) việc triển khai SSDT" khá nhiều, tôi đã thực hiện điều này, vì vậy tôi chưa thực sự triển khai điều này, vì nó đứng Tôi nghĩ đó là lựa chọn duy nhất. Đó là một sự xấu hổ như tôi * thực sự * như ssdt, nhưng tôi đoán hiếm khi, nếu có, bất kỳ viên đạn bạc nào :) –

+0

Chỉ cần đọc lại và tôi xứng đáng được bỏ phiếu để sử dụng cụm từ "viên đạn bạc". Lingo bingo ftw! –

+0

bạn có liên kết cho "thứ tự hoạt động" bạn đã nêu ở trên không? –

Các vấn đề liên quan