回答:
キーを保持すると、1つのキー値が1つのテーブルに格納されます。反例を提示すると、この概念をよりよく理解できる場合があります。
例1:
ビューには集約が含まれています。次のビュー構造があるとします。
GroupID, AverageSalary
1 , 10000
2, 12000
3, 14000
この例では、値は複数の行から取得されます。このビューでAverageSalaryを更新しようとすると、データベースには更新する行を見つける方法がありません。
例2: ビューに複数のテーブルの値が表示されています。ビューには、PERSONおよびPERSON_CONTACT_DETAILS(ID、PersonID、ContactType、ContactValue)テーブルの値が表示されます。
行の例:
1,1,email,ddd@example.com
1,1,phone,898-98-99
この2つのテーブルに参加して、よりビジネスに優しい情報を表示します。
PersonId、Name、LastName、Phone1、Email1
ここでは、Phone1とEmail1を更新します。ただし、この例では、personIDは2つの異なる行にマップされ、さらに多くの行が含まれる場合があります。このビューでも、データベースには更新する行を見つける方法がありません。
注:ビューsqlを制限し、更新する行を見つけることが明確になった場合、動作する可能性があります。
この2つの例は、頭に浮かぶ最初の例です。それらは増やすことができます。しかし、コンセプトは明確です。データベースは、1つのキー値を1つのテーブルにマッピングする必要があります。たとえば、1対1のPERSON、PERSON_DETAILSテーブルがあります。ここでは、1対1であるため、表示と更新が機能します。
ドキュメントすでに読んだことがあるがかなりよくそれを言います。さらに説明するには:
キー保存表の概念は、結合ビューの変更に関する制限を理解するための基本です。
通常、update
1つのテーブルに作用します。フィルター内の曲がりくねったサブクエリを回避するために、Oracle update
は、テーブル内の実際の基礎となる行に行っている変更を簡単にマップできる限り、ビュー(またはサブクエリ)を許可します。これは、set
句が「キー保存」テーブルの列のみを変更する場合に可能です。
テーブルのすべてのキーが結合の結果のキーにもなり得る場合、テーブルはキー保存されます。そのため、キー保存されたテーブルのキーは、結合を通じて保存されます。
例えば:
create table foo( foo_id integer primary key, foo_val integer not null );
create table bar( bar_id integer primary key, bar_val integer not null,
foo_id integer not null references foo );
update (select * from foo join bar using(foo_id)) set foo_val=1;
ORA-01779: cannot modify a column which maps to a non key-preserved table
update (select * from foo join bar using(foo_id)) set bar_val=1;
0 rows updated.
1マッピング:Oracleは1の方法がないため、最初の更新は失敗foo_val
への照会中foo_val
ではfoo
1マップごと:Oracleが1ことができるので、逆に2番目の更新が成功- bar_val
に bar_val
でbar
。重要なことは、それfoo_id
が一意であるということですfoo
-したがって、の各行にはbar
、対応する行は最大で1つしかありませんfoo
(この例では実際には正確に 1ですが、ヌル可能な外部キーにも同じことが当てはまります-ポイントは決して複数の行)。
最初に例を挙げて、後で説明します。Student(t_students)とCourse(t_course)の2つのテーブルを考えます。
- 学生テーブル(stundentid、name、courseid)には、学生IDの主キーがあります。
- コーステーブル(courseid、coursename)には、コースIDの主キーがあります。
これら2つのテーブルが結合されている場合->
select * from t_students S, t_course C where S.courseid=C.courseid;
結果のデータは、Studentsテーブルとまったく同じ行数になります。結果セットにstudentidの重複値はありません(studentidは保持されます)。ただし、コースIDはコーステーブルで一意ですが、多くの学生が同じコースを選択した可能性があるため(結果として、コースIDは保持されません)、結果セットで複数回繰り返されます。
この例を使用すると、次のような結論に達することができます。
- ベーステーブル内のすべてのキーは、join(studentid)後の結果データのキーとして機能します。
- ベース行の行は、結果データに最大で一度だけ表示されます(重複行はありません)
これは、キー保存テーブルの概念です。
ビューの列が更新可能かどうかを知るには、
select * from all_updatable_columns where table_name='V_VIEW_NAME';
PS:大文字でテーブル/ビュー名を提供します。