2

MS Access 用に設計しなければならないデータベースには、特定の測定パラメーター (測定値、標準偏差など) を格納する「測定値」というテーブルがあります。各行には、主キーとして整数 ID があります。

他のテーブルは、外部キー関係を使用してこの測定テーブルにリンクします。一部のテーブルには 2 つの異なる「measurementID」フィールドが含まれており、どちらもこの 1 つの測定テーブルにリンクしています。ただし、各測定値は、これらのフィールドのいずれかによってのみリンクされる必要があります。

複数のテーブルの複数のフィールドに対して一意性制約を適用するにはどうすればよいですか? 方法はありますか?

4

5 に答える 5

3

Microsoft ACE / Jetエンジンはトリガーをサポートしていません。これは、通常、このタイプの機能を実装する方法です。

編集:@onedaywhenが指摘しているように、JET 4.0以降はチェック制約をサポートしていますが、2つの列にxor型制約を実装するのは簡単ではありません。

アクセスフォームを使用している場合は、フォームの更新前イベントを実装して、制約基準を確認できます。

于 2009-04-09T00:22:33.450 に答える
3

このような制約は、制約を使用して ACE/JET に実際に実装できCHECKます。

通常、この種の可能性のためにトリガーを使用すると述べた人は、ACE/Jet と SQL Server のそれぞれの制約の違いを認識していませんCHECK。SQL Server では、サブクエリを含めることはできません。つまり、他の行の値を参照することはできません。同じテーブルまたは他のテーブルに、ACE/Jet では可能です。

理想的な (しかしまだ存在しない) SQL-92 製品では、記述された一意性はASSETION、スキーマ レベルである を使用して実装されます。CHECK 制約はテーブル レベルであり、それらが定義されているテーブルがUPDATEd またはINSERTed である場合にのみチェックされるため、すべての参照テーブルに適切な制約を設定する必要がありCHECKます (SQL Server トリガーにも同じことが適用されます)。簡単な例を次に示します。

CREATE TABLE Parent 
(
   parent_ID INTEGER NOT NULL IDENTITY UNIQUE, 
   data_col INTEGER NOT NULL
)
;
CREATE TABLE Child1
(
   parent_ID INTEGER NOT NULL
      REFERENCES parent (parent_ID), 
   data_col INTEGER NOT NULL
)
;
CREATE TABLE Child2
(
   parent_ID INTEGER NOT NULL
      REFERENCES parent (parent_ID), 
   data_col INTEGER NOT NULL
)
;
ALTER TABLE Child1 ADD
   CONSTRAINT child1__no_dups_in_child2
   CHECK (NOT EXISTS (
                      SELECT * 
                        FROM Child1 AS C1
                             INNER JOIN Child2 AS C2
                                ON C1.parent_ID = C2.parent_ID
                     ))
;
ALTER TABLE Child2 ADD
   CONSTRAINT child2__no_dups_in_child1
   CHECK (NOT EXISTS (
                      SELECT * 
                        FROM Child1 AS C1
                             INNER JOIN Child2 AS C2
                                ON C1.parent_ID = C2.parent_ID
                     ))
;

FOREIGN KEYただし、サブクラスがあるかどうかは疑問です (つまり、ID で表される各エンティティを型指定できます)。その場合、 s と行レベルのCHECK制約 (または MS に慣れている場合は検証規則)を使用できるはずです。CHECK制約に必要な SQL DLL よりもアクセス インターフェイス)。このロジックは、テーブル レベルのCHECK制約よりも簡単に実装できますCASCADE。参照アクションの循環に注意するだけです。別の簡単な例を次に示します。

CREATE TABLE Parent 
(
   parent_ID INTEGER NOT NULL IDENTITY, 
   child_type VARCHAR(4) NOT NULL, 
   CONSTRAINT child_type__values 
      CHECK (child_type IN ('Boy', 'Girl')), 
   UNIQUE (child_type, parent_ID)
)
;
CREATE TABLE Girls
(
   parent_ID INTEGER NOT NULL, 
   child_type VARCHAR(4) DEFAULT 'girl' NOT NULL, 
   CONSTRAINT girl_child_type__must_be_girl
      CHECK (child_type = 'girl'),
   FOREIGN KEY (child_type, parent_ID)
      REFERENCES Parent (child_type, parent_ID), 
   data_col INTEGER NOT NULL
)
;
CREATE TABLE Boys
(
   parent_ID INTEGER NOT NULL, 
   child_type VARCHAR(4) DEFAULT 'boy' NOT NULL, 
   CONSTRAINT boy_child_type__must_be_boy
      CHECK (child_type = 'boy'),
   FOREIGN KEY (child_type, parent_ID)
      REFERENCES Parent (child_type, parent_ID), 
   data_col INTEGER NOT NULL
)
;
于 2009-04-09T08:28:07.683 に答える
0

このデータベースを設計していると仮定します。テーブル構造が標準の正規化ルールに従っていることを確認してください。

表示しているA.rowフィールドに応じて、テーブルMeasurementsの2つの行を参照できるのは、テーブルAの行の異常な構造に聞こえます。テーブルMeasurmentsのデータは、実際には2つ以上のテーブルに分割する必要があると感じています。

于 2009-04-09T01:33:44.870 に答える
0

私自身、トリガーとチェック制約に警戒しています。これは主に、ほとんどのアプリをそれらなしで開発してきたためです (Access/Jet および MySQL/MyISAM)。これはスーパータイプ/サブタイプの状況のように聞こえるというボブクレッグに同意します。その場合、外部キーの一意のインデックスと、それがどのタイプの測定であったかを示す列を持つ結合テーブルを使用します。FK の一意のインデックスは、2 番目のタイプの追加を防ぎます。また、メイン レコードに空のフィールドがないことも意味します。確かに、1 つの空の数値フィールドはストレージの問題ではありませんが、排他的な 2 つのフィールドは常に設計エラーのように見えます。

于 2009-04-09T22:07:19.467 に答える
0

Mitch は、Access で何ができるかについて正しいです。ただし、どこかに BL があると仮定すると、これはビジネス ルールとして正当なものに端を発しています。それが私が最もやりそうなことです。

于 2009-04-09T00:37:21.340 に答える