2016-10-03 20 views
0

基本的には、自分がサービスする郵便番号を所有する「ビジネス」があるとします。また、別の関係テーブルを使って手数料を設定しているとしましょう。外部キーの外部キーがベース外部キーと一致することを確認する

CREATE TABLE [dbo].[BusinessPostalCodes] 
(
    [BusinessPostalCodeId]   INT   IDENTITY (1, 1) NOT NULL, 
    [BusinessId]     INT   NOT NULL, 
    [PostalCode]     VARCHAR (10) NOT NULL 
) 

CREATE TABLE [dbo].[BusinessPostalCodeFees] 
(
    [BusinessId] INT NOT NULL, 
    [BusinessProfileFeeTypeId] INT NOT NULL, 
    [BusinessPostalCodeId] INT NOT NULL, 
    [Fee] SMALLMONEY NULL 
) 

私はそれがBusinessPostalCodesの関連BusinessIdBusinessPostalCodeFeesBusinessIdと同じであることを確実にBusinessPostalCodeFeesに外部キー(または何か)を設定することが可能ですかどうかを知りたいです。

私はBusinessIdを完全に削除できることを認識していますが、私はずっとこの列を保持し、同じであることを保証する方法があります。何か私にできることはありますか?

+0

は、トリガーであなたのロジックを記述し、違反したトランザクションをロールバックあなたのルール – techspider

+0

@techspiderヒントのためにありがとう、しかし私はチェックされた制約がここで本当にうまくいったと思います。 –

答えて

0

最後に、ジェフリーのソリューションは、私の特定の状況にかなりの仕事をしませんでした。リレーションの両方の列は、コンポジットキーのように一意でなければなりません。ここでの答えは(私のために)であり、チェックされた制約です。

あなたが制約パスを持っているか、失敗する関数を作成します。それからちょうどあなたのテーブルに追加

CREATE FUNCTION [dbo].[MatchingBusinessIdPostalCodeAndProfileFeeType] 
(
    @BusinessId int, 
    @BusinessPostalCodeId int, 
    @BusinessProfileFeeTypeId int 
) 
RETURNS BIT 
AS 
BEGIN 

    -- This works because BusinessPostalCodeId is a unique Id. 
    -- If businessId doesn't match, its filtered out. 
    DECLARE @pcCount AS INT 
    SET @pcCount = (SELECT COUNT(*) 
     FROM BusinessPostalCodes 
     WHERE BusinessPostalCodeId = @BusinessPostalCodeId AND 
      BusinessId = @BusinessId) 


    -- This works because BusinessProfileFeeTypeId is a unique Id. 
    -- If businessId doesn't match, its filtered out. 
    DECLARE @ftCount AS INT 
    SET @ftCount = (SELECT COUNT(*) 
     FROM BusinessProfileFeeTypes 
     WHERE BusinessProfileFeeTypeId = @BusinessProfileFeeTypeId AND 
      BusinessId = @BusinessId) 

    -- Both should have only one record 
    BEGIN IF (@pcCount = 1 AND @ftCount = 1) 
     RETURN 1 
    END 

    RETURN 0 
END 

を:

CONSTRAINT [CK_BusinessPostalCodeFees_MatchingBusinessIdPostalCodeAndProfileFeeType] 
CHECK (dbo.MatchingBusinessIdPostalCodeAndProfileFeeType(
    BusinessId, 
    BusinessPostalCodeId, 
    BusinessProfileFeeTypeId) = 1) 
1

BusinessPostalCodeFeesのBusinessIdおよびBusinessPostalCodeId列への入力がBusinessPostalCodes表の項目と一致することを確認しようとしているような感じです(私が間違っていれば修正します)。その場合、はい、あなたはdefinitely have a foreign key that references a compound primary keyです。

ただし、BusinessIdを維持する必要がある場合は、テーブルを正規化することをお勧めします。あなたはそのままの状態でデータを重複させるでしょう。サイドノートでは

、私はあなたがSQLにお金のデータ型を使用していないお勧めします:See here.

+0

私は全くそのようにそれについて考えることはありませんでしたが、多くの意味があります。私はあなたが正しいと思っていますが、私は最終的にはそれを少し難しく見て正規化すべきです。これは素晴らしい情報です、ありがとう! –

+0

あなたは幸せなdatabasingです! –

+0

あなたが気にしない場合は、フォローアップを1回行ってください。郵便番号と手形にはどちらもBusinessIdがあります。それらの一致を保証する方法はありますか? –