0

データベースに 2 つのテーブルがあるとします。1 つ目は X、2 つ目は Y です。Y テーブルは X テーブルに外部キーを持っています。したがって、Y テーブルにレコードがある場合、その外部キー関連の列の値は X テーブルに存在する必要があります。これがデフォルトの動作です。

   X         Y
-------   -------
  ID        ID
            XID <--- Foreignkey to X table.

ここで、X テーブルのすべてのレコードについて、Y テーブルに少なくとも 1 つのレコードが必要であることを保証したいと考えています。ない場合は、自動的に追加する必要があります。これどうやってするの?

4

2 に答える 2

1

欠落したレコードを既存のデータに挿入するにはY、次のようなものを実行できます

INSERT INTO Y(xid)
SELECT x.id 
FROM x 
WHERE NOT EXISTS(SELECT NULL FROM Y a WHERE a.xid = x.id);

今後このようなことを防ぐには、2 つのテーブルにデータを挿入する手順を記述し、誰もがテーブルに直接データを挿入できないようにします (この手順のみ)。

于 2012-12-16T13:30:17.960 に答える
1

ここには 2 つの異なる問題があります。

  1. 宣言的制約の管理。
  2. 挿入、更新、および削除の管理。

x のすべての行に対して y に行が存在することを保証する「通常の」方法は、両方のテーブルに外部キーを含めることです。各テーブルは他のテーブルを参照します。

create table x (
  x_id integer primary key,
  y_id integer not null
);

create table y (
  y_id integer primary key,
  x_id integer not null references x (x_id)
);

alter table x
add constraint one_to_one
foreign key (y_id)
  references y (y_id) deferrable initially deferred;

begin transaction;
insert into x values (1, 100);
insert into y values (100, 1);
commit;

これは、すべての "x" が "y" を持つことを保証しますが、いわば、すべての "x" が異なる"y" を持つこと、またはすべての "x" が独自の "y" を持つことを保証するものではありません。それがあなたの要件かどうかはわかりません。

2 つのテーブル間に 1:N の関係があるため、これは探しているものとは異なります機能させることはできますが、テーブル「y」への変更を管理するトリガーを作成する必要があると思います。たとえば、ユーザーが「x」が外部キー参照を保持している行を「y」から削除した場合、「x」を更新して「y」の別の行を参照する必要があります。

しかし、これは 2 番目の問題、つまり挿入、更新、および削除の管理につながります。それにはいくつかの方法があります。

  • クライアントは、データベースの一貫性を保つために必要なすべてのステートメントを提供する責任があります。(上記の外部キーの問題の可能性のある例外を除いて、「y」のトリガーで処理する方がよい場合があります。)
  • クライアントはベース テーブルに直接アクセスできません。すべての変更は、ストアド プロシージャを介して行われます。
  • クライアントはベース テーブルに直接アクセスできません。すべての変更は、更新可能なビューを通じて行われます。

ストアド プロシージャと更新可能なビューを使用すると、"y" に行を自動的に追加できますが、そのためには手続き型のコードを記述する必要があります。

于 2012-12-16T14:57:33.037 に答える