0

すべての外部キー/照合の質問を約 1 時間検索してみましたが、私の質問に少しでも近いものが見つかりません。

同じデータベースに 2 つの異なるソフトウェア ベンダーの 2 つのテーブルがあります。一方のベンダーは照合順序を Latin1_General_BIN にハード コードし、もう一方のベンダーはデータベース デフォルト (この場合は Latin1_General_CI_AS) を使用します。列を変更せずに、これら 2 つの照合タイプの間に外部キーを作成することは可能ですか?

通常は 1 つを変更するだけですが、この場合、テーブルは非常に機密性が高く、そのような変更を行うことはできませんが、これら 2 つのテーブル間のデータを読み取るトリガーのロジックのために外部キーを作成する必要があります。外部キーが見つかった場合のみ:

SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE 
WHERE CONSTRAINT_NAME = 
( 
    SELECT name FROM sys.foreign_keys 
    WHERE parent_object_id = OBJECT_ID( 'Table1' )
    AND referenced_object_id = OBJECT_ID( 'Table2' ) 
)

どんな助けでも本当に感謝します

PS誰かが私を助けてくれれば、このコードがどのように機能するのか理解できないようです.4つの必要なスペースを入れましたが、それでも私のコードをテキストとして表示しています:(

4

2 に答える 2

0

スイート、ソリューションは非常にエレガントだと思います。必要なソリューションに最も近い完全な代替手段であるため、純粋に回答として書いています。しかし、それは私の元の質問に正しく答えるものであるため、あなたの答えを答えとしてマークします。

そうです、最初に私がしたことは、トリガーが外部キーを必要とするベンダーから、他のベンダー テーブルの照合で永続化された計算列としてテーブルに新しい列を作成する許可を得たことです。

DECLARE @Collation  nvarchar(100)
DECLARE @SQL        nvarchar(1000)
SET @Collation = ( SELECT collation_name FROM sys.columns WHERE OBJECT_ID IN ( SELECT OBJECT_ID FROM sys.objects WHERE type = 'U' AND name = 'Vendor1Table' ) AND name = 'Vendor1Column' )
SET @SQL = 'ALTER TABLE [Vendor2Table] ADD [Vendor2ComputedColumn] AS [Vendor2Column] COLLATE ' + @Collation + ' PERSISTED'
EXECUTE( @SQL )
GO

次に、計算列に候補キーを追加しました。

ALTER TABLE [Vendor2Table] ADD CONSTRAINT [CCUNQ1_x] UNIQUE NONCLUSTERED 
(
    [Vendor2ComputedColumn] ASC
)
WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) 
ON [PRIMARY]
GO

次に、計算列への外部キーを作成しました。

ALTER TABLE [dbo].[Vendor1Table]  WITH CHECK ADD CONSTRAINT [CCFOK01_x] FOREIGN KEY ( [Vendor1Column] )
REFERENCES [dbo].[Vendor2Table] ( [Vendor2ComputedColumn] )
GO

ALTER TABLE [dbo].[Vendor1Table] CHECK CONSTRAINT [CCFOK01_x]
GO

最後に、元の SQL スクリプトは見事に合格します。

SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE 
WHERE CONSTRAINT_NAME = 
( 
    SELECT name FROM sys.foreign_keys 
    WHERE parent_object_id = OBJECT_ID( 'Vendor1Table' )
    AND referenced_object_id = OBJECT_ID( 'Vendor2Table' ) 
)

うまくいけば、この小さなウォークスルーがいつか他の魂を助けるでしょう:)

デビッドを助けてくれてありがとう、ありがとう!

于 2013-07-18T13:54:38.213 に答える
0

ある照合のフィールドから別の照合のフィールドに外部キー制約を追加することはできません。エラー メッセージ 1757 が表示されます。

いずれかのテーブルの照合を変更するか、正しい照合で代わりに使用される新しい列で回避策を作成するか、参照に使用される整数で代理キー列を作成します。

他に何も機能せず、このタイプの制約を本当に修正する必要があり、パフォーマンスが問題にならない場合は、チェック制約および/またはテーブルに配置されたデータの参照整合性をチェックするトリガーを追加します。これらのルールは、値を比較するために、1 つのテーブルのすべての値を他のテーブルの照合にキャストする必要があるため、処理が遅くなり、インデックスを使用するのが非常に難しくなります。慎重に進めてください。

たとえば、挿入された文字列を含むレコードが参照先テーブルに存在するかどうかを確認する、参照元テーブルに挿入トリガーを設定できます。次に、参照テーブルのレコードによって参照される値の範囲、または更新/削除をカスケードする値の範囲外にならないように、参照テーブルの更新および削除トリガーも追加する必要があります。基本的に、外部キーとは何かを複製すると、非常に遅くなり、恐ろしくスケーリングします。

簡単な答え: しないでください。テーブルを結び付けないままにするか、テーブルの 1 つの照合を修正します。

于 2013-07-18T11:55:25.803 に答える