Tắt các ràng buộc tạm thời (MS SQL)


208

Tôi đang tìm cách tắt tạm thời tất cả các ràng buộc của DB (ví dụ: các mối quan hệ bảng).

Tôi cần sao chép (sử dụng INSERT) một bảng DB sang DB khác. Tôi biết tôi có thể đạt được điều đó bằng cách thực hiện các lệnh theo đúng thứ tự (để không phá vỡ các mối quan hệ).

Nhưng sẽ dễ dàng hơn nếu tôi có thể tắt kiểm tra các ràng buộc tạm thời và bật lại sau khi kết thúc thao tác.

Điều này có thể không?


3
Đây không phải là bản sao hoàn chỉnh Tôi chỉ muốn sao chép các bảng đã chọn giữa
Maciej

Mối quan tâm của tôi về việc này là điều này sẽ tắt các ràng buộc cho tất cả mọi người không chỉ riêng bạn. Nếu bạn phải làm điều này, hãy đặt cơ sở dữ liệu ở chế độ người dùng duy nhất trước. Nếu không, bạn có thể kết thúc vấn đề toàn vẹn dữ liệu.
HLGEM

13
Kính gửi mọi người từ Tương lai: Bạn có thể vô hiệu hóa và kích hoạt lại tất cả các ràng buộc trong cơ sở dữ liệu cùng một lúc; xem stackoverflow.com/a/161410
brichins

1
Đừng quên bật các ràng buộc, khi hoàn tất!
Mike Christian

1
@NicolasBarbulesco đủ công bằng; Tôi đã đi ra sql-serversql-server-2005các thẻ. Liên kết tôi đưa ra là dành cho SQL Server, nhưng bạn có thể làm điều tương tự trong Oracle - xem tại đâyđây . Bạn cũng có thể làm điều đó trong PostgreSQL .
brichin

Câu trả lời:


214

Bạn chỉ có thể vô hiệu hóa các ràng buộc FK và CHECK trong SQL 2005+ . Xem BẢNG ALTER

ALTER TABLE foo NOCHECK CONSTRAINT ALL

hoặc là

ALTER TABLE foo NOCHECK CONSTRAINT CK_foo_column

Các khóa chính và các ràng buộc duy nhất không thể bị vô hiệu hóa, nhưng điều này sẽ ổn nếu tôi hiểu đúng về bạn.


10
Nhưng đây không phải là tạm thời.
Nicolas Barbulesco

@NicolasBarbulesco: nó phụ thuộc. Đúng vậy, ở chỗ bạn có thể kích hoạt lại chúng bằng DROP / CREATE
gbn

Câu trả lời này chỉ là nửa đầu của một giải pháp. Tôi đang tìm kiếm một cách đơn giản để tắt các ràng buộc tạm thời và tôi đã đi đến kết luận rằng nó không tồn tại, trên Oracle.
Nicolas Barbulesco

Không phải là PK và ràng buộc duy nhất không thể bị vô hiệu hóa. Ít nhất là trong phiên bản gần đây hơn của SQL Server, nó hoạt động. Ví dụ: xem: techonthenet.com/sql_server/primary_keys.php
Dejan

1
@NicolasBarbulesco trên Oracle? THAY ĐỔI BẢNG some_table DISABLE CONSTRAINT some_table_fk1; // thực hiện một số nội dung có thể vi phạm các ràng buộc ALTER TABLE some_table ENABLE CONSTRAINT some_table_fk1;
Steve Swinsburg

237
-- Disable the constraints on a table called tableName:
ALTER TABLE tableName NOCHECK CONSTRAINT ALL

-- Re-enable the constraints on a table called tableName:
ALTER TABLE tableName WITH CHECK CHECK CONSTRAINT ALL
---------------------------------------------------------

-- Disable constraints for all tables:
EXEC sp_msforeachtable 'ALTER TABLE ? NOCHECK CONSTRAINT all'

-- Re-enable constraints for all tables:
EXEC sp_msforeachtable 'ALTER TABLE ? WITH CHECK CHECK CONSTRAINT all'
---------------------------------------------------------

1
@kevinc không. Miễn là bạn đồng ý thì không vấn đề gì.
Po-ta-toe

2
Sử dụng số nhận dạng được trích dẫn là tôi tin rằng cài đặt tiêu chuẩn ANSI, có nghĩa là bạn không nên sử dụng chúng cho chuỗi. Không có gì để làm với sự nhất quán. xem stackoverflow.com/questions/1992314/
Mạnh

1
Cảm ơn các thủ tục! Và BTW, vỏ chính xác của nó là "sp_MSforeachtable" (chữ hoa MS). Cảm ơn!
Sielu

3
Điều này nên được đánh dấu là câu trả lời đúng vì nó trả lời hoàn toàn câu hỏi. Không chỉ vậy, nhưng @Donal bao gồm một phiên bản ký tự đại diện rất hữu ích cho tôi.
Matt Jackson

2
Cảm ơn cho bit kích hoạt lại. Đặc biệt là đôi check checkmà nhiều người quên !!
Alex

57

Và, nếu bạn muốn xác minh rằng bạn đã phá vỡ các mối quan hệ của mình và giới thiệu trẻ mồ côi, một khi bạn đã trang bị lại séc của mình, tức là

ALTER TABLE foo CHECK CONSTRAINT ALL

hoặc là

ALTER TABLE foo CHECK CONSTRAINT FK_something

sau đó bạn có thể chạy lại và thực hiện cập nhật đối với bất kỳ cột nào được kiểm tra như vậy:

UPDATE myUpdatedTable SET someCol = someCol, fkCol = fkCol, etc = etc

Và bất kỳ lỗi nào tại thời điểm đó sẽ là do không đáp ứng các ràng buộc.


11
Cách tốt hơn là ALTER TABLE FOO WITH CHECK ràng buộc kiểm tra FK_something
Cody Konior

1
ALTER TABLE foo KIỂM TRA CONSTRAINT ALL hoặc ALTER TABLE foo KIỂM TRA CONSTRAINT FK_s Something sẽ kích hoạt các ràng buộc nhưng không kiểm tra dữ liệu và điều này có nghĩa là ràng buộc đó sẽ không đáng tin cậy (is_no_trust = 1, is_disables = 0).
Bogdan Sahlean


0

Vô hiệu hóa và kích hoạt tất cả các khóa ngoại

CREATE PROCEDURE pr_Disable_Triggers_v2
    @disable BIT = 1
AS
    DECLARE @sql VARCHAR(500)
        ,   @tableName VARCHAR(128)
        ,   @tableSchema VARCHAR(128)

    -- List of all tables
    DECLARE triggerCursor CURSOR FOR
        SELECT  t.TABLE_NAME AS TableName
            ,   t.TABLE_SCHEMA AS TableSchema
        FROM    INFORMATION_SCHEMA.TABLES t
        ORDER BY t.TABLE_NAME, t.TABLE_SCHEMA

    OPEN    triggerCursor
    FETCH NEXT FROM triggerCursor INTO @tableName, @tableSchema
    WHILE ( @@FETCH_STATUS = 0 )
    BEGIN

        SET @sql = 'ALTER TABLE ' + @tableSchema + '.[' + @tableName + '] '
        IF @disable = 1
            SET @sql = @sql + ' DISABLE TRIGGER ALL'
        ELSE
            SET @sql = @sql + ' ENABLE TRIGGER ALL'

        PRINT 'Executing Statement - ' + @sql
        EXECUTE ( @sql )

        FETCH NEXT FROM triggerCursor INTO @tableName, @tableSchema

    END

    CLOSE triggerCursor
    DEALLOCATE triggerCursor

Đầu tiên, con trỏ ForeignKeyCthon được khai báo là câu lệnh SELECT tập hợp danh sách các khóa ngoại và tên bảng của chúng. Tiếp theo, con trỏ được mở và câu lệnh FETCH ban đầu được thực thi. Câu lệnh FETCH này sẽ đọc dữ liệu của hàng đầu tiên vào các biến cục bộ @ForignKeyName và @tableName. Khi lặp qua một con trỏ, bạn có thể kiểm tra @@ FETCH_STATUS cho giá trị 0, cho biết quá trình tìm nạp đã thành công. Điều này có nghĩa là vòng lặp sẽ tiếp tục di chuyển về phía trước để nó có thể nhận được mỗi khóa ngoại liên tiếp từ hàng. @@ FETCH_STATUS có sẵn cho tất cả các con trỏ trên kết nối. Vì vậy, nếu bạn đang lặp qua nhiều con trỏ, điều quan trọng là phải kiểm tra giá trị của @@ FETCH_STATUS trong câu lệnh ngay sau câu lệnh FETCH. @@ FETCH_STATUS sẽ phản ánh trạng thái cho hoạt động FETCH gần đây nhất trên kết nối. Các giá trị hợp lệ cho @@ FETCH_STATUS là:

0 = FETCH đã thành công
-1 = FETCH không thành công
-2 = hàng được tìm nạp bị thiếu

Bên trong vòng lặp, mã xây dựng lệnh ALTER TABLE khác nhau tùy thuộc vào ý định là vô hiệu hóa hoặc kích hoạt ràng buộc khóa ngoại (sử dụng từ khóa CHECK hoặc NOCHECK). Câu lệnh sau đó được in dưới dạng tin nhắn để tiến trình của nó có thể được quan sát và sau đó câu lệnh được thực thi. Cuối cùng, khi tất cả các hàng đã được lặp qua, thủ tục được lưu sẽ đóng và giải phóng con trỏ.

xem Vô hiệu hóa các ràng buộc và kích hoạt từ Tạp chí MSDN

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.