2013-05-01 9 views
9

私は2つのテーブル、SaleとProductを持っています。 Saleには、Productを参照する外部キー制約があります。外部キーはWITH NOCHECKで作成され、作成後すぐに無効になりました。私は、外部キー制約を有効にして信頼したいと思います。それを有効にすることはできますが、私はそれを信頼できるものにすることはできません。 StackOverflowの様々なブログ上外部キー制約を信頼できるようにする方法

同様の質問がALTER TABLE T WITH CHECK CHECK CONSTRAINT Cを実行するとis_disabled=0is_not_trusted=0になる必要があることを示しますが、is_not_trustedはいつも私のための1です。私は間違って何をしていますか?

私はSQLフィドルにサンプルコードを入れてみましたが、それはそうここにある、「DBCC」コマンドを好きではなかった:あなたの例に基づいて

-- "_Scratch" is just a sandbox DB that I use for testing stuff. 
USE _Scratch 

CREATE TABLE dbo.Product 
(
    ProductKeyId INT PRIMARY KEY NOT NULL, 
    Description VARCHAR(40) NOT NULL 
) 

CREATE TABLE dbo.Sale 
(
    ProductKeyId INT NOT NULL, 
    SaleTime DATETIME NOT NULL, 
    Value MONEY NOT NULL 
) 

ALTER TABLE dbo.Sale WITH NOCHECK 
    ADD CONSTRAINT FK_Product_ProductKeyId FOREIGN KEY (ProductKeyId) 
    REFERENCES dbo.Product (ProductKeyId) NOT FOR REPLICATION; 

ALTER TABLE dbo.Sale NOCHECK CONSTRAINT FK_Product_ProductKeyId 

INSERT INTO dbo.Product VALUES (1, 'Food') 
INSERT INTO dbo.Sale VALUES (1, GETDATE(), 1.00) 

-- Check the disabled/trusted state 
SELECT name, is_disabled, is_not_trusted 
FROM sys.foreign_keys 
WHERE name = 'FK_Product_ProductKeyId' 

    -- name      is_disabled is_not_trusted 
    -- FK_Product_ProductKeyId 1   1 

-- Check the FK_Product_ProductKeyId constraint 
DBCC CHECKCONSTRAINTS('FK_Product_ProductKeyId') 

    -- DBCC execution completed. 
    -- If DBCC printed error messages, contact your system administrator. 

-- Check all constraints on Sale table 
DBCC CHECKCONSTRAINTS('Sale') 

    -- DBCC execution completed. 
    -- If DBCC printed error messages, contact your system administrator. 

-- Add the constraint and check existing data 
ALTER TABLE Sale WITH CHECK CHECK CONSTRAINT FK_Product_ProductKeyId 

-- Check the disabled/trusted state 
SELECT name, is_disabled, is_not_trusted 
FROM sys.foreign_keys 
WHERE name = 'FK_Product_ProductKeyId' 

    -- name      is_disabled is_not_trusted 
    -- FK_Product_ProductKeyId 0   1 

-- Check the FK_Product_ProductKeyId constraint 
DBCC CHECKCONSTRAINTS('FK_Product_ProductKeyId') 

    -- DBCC execution completed. 
    -- If DBCC printed error messages, contact your system administrator. 

-- Check all constraints on Sale table 
DBCC CHECKCONSTRAINTS('Sale') 

    -- DBCC execution completed. 
    -- If DBCC printed error messages, contact your system administrator. 

答えて

17

、私も試してみました:

  • 外部キーを削除して再作成します。
  • テーブルを削除して再作成します。

それから私は、コマンドで何かに気づいた:

NOT FOR REPLICATION 

制約が複製のために、NOTを使用して作成されている場合、それは常に信頼されていないようです。

Books Onlineから引用:

をいくつかのケースでは、それは複製 トポロジにおけるユーザの活動のための望ましい薬剤活性は異なる扱われるべきです。たとえば、 パブリッシャでユーザーによって行が挿入され、 がテーブルにチェック制約を満たしている場合、 レプリケーションによって行が挿入されたときに同じ制約が適用されることはありません。 加入者。 NOT FOR REPLICATIONオプションは、レプリケーションエージェントが操作を実行する場合は、次のデータベース・オブジェクトは、異なる に処理されるように指定 にことができます:

外部キー制約を

外部キー制約が適用されていない場合、レプリケーション・エージェント 挿入操作、更新操作、または削除操作を実行します。

IS_NOT_TRUSTED設定がの影響を受けて複製ため のみ関連しように見えます。私はあなたが作業しているサーバーで制約が強制されている限り、それはうまくいくはずです。だから私は先に行って、それを確認した:

SELECT name, is_disabled, is_not_trusted 
FROM sys.foreign_keys 
WHERE name = 'FK_Product_ProductKeyId' 

name     is_disabled is_not_trusted 
FK_Product_ProductKeyId 0   1 

INSERT INTO dbo.Sale VALUES (2, GETDATE(), 1.00) 

Msg 547, Level 16, State 0, Line 1 
The INSERT statement conflicted with the FOREIGN KEY constraint "FK_Product_ProductKeyId". The conflict occurred in database "_Scratch", table "dbo.Product", column 'ProductKeyId'. 
The statement has been terminated. 

あなたはまだ心の平和のためにIS_NOT_TRUSTED = 0を見たい場合は、単にNOT FOR REPLICATIONせずに外部キーを再作成します。

あなたの疑問がある場合は、CHECK制約についても同様の効果があることを確認しました。

+0

ルーイ、テストをする時間を取ってくれてありがとう、それは素晴らしい答えです、私はあなたに複数のupvoteを与えることができたらいいと思っています:)私は、一部のクエリのパフォーマンスに影響を与える可能性があります。私はデータベースを継承し、複製はしませんが、すべてが "投機的ではない"と思われます。これは "投機的な一般性"のケースかもしれません。 – WileCau

+0

@WileCau FKが信頼されていないとマークされている場合、実際には実行時間が改善されます。私はこの練習を励ますことは決してありません。しかし、大量のデータをステージングするsqlからプロダクションsqlに移動することは非常に便利です。詳細はこちらhttp://sqlblog.com/blogs/hugo_kornelis/archive/2007/03/29/can-you-trust-your-constraints.aspx – harsimranb

+0

@ Pathachiever11、そうです、制約が無効になった理由いくつかのテーブルが最初に別の既知の一貫性のあるデータベースから移入されたので、データ移行が遅くなったからです。最初の移行後、制約は新しいデータに一貫性を持たせるために再び有効にされていたはずですが、それらは忘れてしまっていました。 – WileCau

関連する問題