1

次のようなテーブルがあります。

CREATE TABLE A (
  A_UNIQUE_ID int NOT NULL PRIMARY KEY,
  A_OTHER_ID int NOT NULL,
  A_CURRENT_FL bit NOT NULL )

そして、これに似た値を持っています

INSERT INTO TABLE A VALUES (1, 1, 0);
INSERT INTO TABLE A VALUES (2, 1, 0);
INSERT INTO TABLE A VALUES (3, 1, 1);

このような別のテーブルBを作成したい

CREATE TABLE B (
  B_UNIQUE_ID int NOT NULL PRIMARY KEY,
  A_OTHER_ID int NOT NULL)

whereB.A_OTHER_IDは A の一意の行に制約されB.A_OTHER_ID = A.A_OTHER_ID AND A.CURRENT_FL = 1ます。ある種のチェック制約設定でそれは可能ですか? 例は非常に高く評価されています。

4

2 に答える 2

0

いくつかの計算された列でそれを行うことができますが、あまりきれいに見えません:

CREATE TABLE A (
  A_UNIQUE_ID int NOT NULL PRIMARY KEY,
  A_OTHER_ID int NOT NULL,
  A_CURRENT_FL bit NOT NULL,
  OTHER_XREF as CASE WHEN A_CURRENT_FL = 1 THEN A_OTHER_ID END persisted,
  UNIQ as CASE WHEN A_CURRENT_FL = 0 THEN A_UNIQUE_ID ELSE 0 END persisted 
  constraint UQ_OTHER_XREF UNIQUE (OTHER_XREF,UNIQ)
  )

INSERT INTO A VALUES (1, 1, 0);
INSERT INTO A VALUES (2, 1, 0);
INSERT INTO A VALUES (3, 1, 1);

CREATE TABLE B (
  B_UNIQUE_ID int NOT NULL PRIMARY KEY,
  A_OTHER_ID int NOT NULL,
  XREF as 0 persisted,
  constraint FK_B_A FOREIGN KEY (A_OTHER_ID,XREF) references A (OTHER_XREF,UNIQ))

これは機能します:

  insert into B VALUES (2,1)

これにより、FK 制約が破られます。

  insert into B VALUES (3,2)

テーブル A の 2 つの計算列により、A_CURRENT_FL=を含むすべての行が1内の個別の値としてそれを持つことが保証されOTHER_XREFます。他の行はNULLその列に含まれます。ただし、制約 (外部キーのターゲット) を適用するには、 =を持つ行の既知の値でありながら、 をUNIQUE持つ行ごとに明確に異なるものが必要です。この場合、既知の値を にしました。NULLA_CURRENT_FL10

最後に、外部キー制約はこれらの列の両方に一致する必要があるため、既知の値を持つ新しい計算列をテーブル B に追加します0

列名は特に良いものではありませんが、いくつか思い付くことができると確信しています。


また、上記により、言及されていない別の制約も実装されていることに注意してください。ただし、これも重要な場合があります。現在、テーブル A に両方がA_CURRENT_FL1 に設定されている 2 つの行はありません。同じA_OTHER_ID値。これもエラーを生成します。

INSERT INTO A VALUES (4,1,1);
于 2012-09-07T07:46:46.213 に答える
0

上記で説明したように、テーブル A を一意にするためにテーブル A に制約が必要です。この回答を使用して、関数を作成し、新しいチェック制約でそれを呼び出すことができます。例えば:

CREATE FUNCTION Check_A_CURRENT_FL_Count(@Id INT) RETURNS INT AS 
BEGIN
  DECLARE @ret INT;
  SELECT @ret = COUNT(*) FROM A WHERE A_OTHER_ID = @Id AND A_CURRENT_FL = 1;
  RETURN @ret;
END
GO

alter table A add constraint [CK_A] CHECK (NOT (dbo.Check_A_CURRENT_FL_Count(A_OTHER_ID) > 1 AND A_CURRENT_FL = 1))
GO

次に、あなたが何を望んでいるかを正しく理解していれば、テーブルBのチェック制約で同じ関数を使用できます。明らかに不自然な例を使用していますが、これの目的が何であるかは完全にはわかりません。テーブル A の一意の ID のリストが必要な場合は、テーブル B の主キーとして A_OTHER_ID を使用し、B_UNIQUE_ID を取り除くことができますか?

于 2012-09-07T07:39:41.463 に答える