Answers:
保留键表示1个键值进入1个表。提供反例可以帮助您更好地理解此概念。
范例1:
您的视图包含聚合。假设您具有以下视图结构。
GroupID, AverageSalary
1 , 10000
2, 12000
3, 14000
在此示例中:您的值来自多个行。如果尝试在此视图中更新AverageSalary,则数据库将无法找到要更新的WHICH行。
示例2: 您的视图显示多个表中的值。您的视图显示了PERSON和PERSON_CONTACT_DETAILS(ID,PersonID,ContactType,ContactValue)表中的值。
示例行:
1,1,email,ddd@example.com
1,1,phone,898-98-99
您加入此2表并在视图中显示更多业务友好信息。
PersonId,姓名,姓氏,电话1,电子邮件1
在这里,您要更新Phone1和Email1。但是在此示例中,您的personID映射到两个不同的行,可能会更多。同样,在此视图中,数据库无法找到要更新的WHICH行。
注意:如果您限制视图sql并明确查找要更新的行,则它可能会起作用。
这两个例子是我想到的第一个例子。它们可以增加。但是概念很明确。数据库需要将1个键值映射到1个表。例如,您有一对一的PERSON,PERSON_DETAILS表。因为它是一对一的,所以在这里可以查看和更新。
您已经阅读的文档说得很好。进一步说明:
保留键表的概念对于理解修改联接视图的限制至关重要。
通常,一个update
作用于单个表。为了避免过滤器中的曲折子查询,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 - bar_val
至 bar_val
中bar
。重要的是,foo_id
在是唯一的foo
-所以在每一行bar
,只能有对应行中最多有一个foo
(实际上正是在这个例子中1,但同样也适用于空的外键-问题是,从未有多于一排)。
让我先举一个例子,然后再解释。考虑两张桌子的学生(t_students)和课程(t_course)。
- 学生表(stundentid,姓名,课程ID)在学生ID上具有主键。
- 课程表(courseid,coursename)具有课程ID的主键。
当这两个表连接在一起时->
select * from t_students S, t_course C where S.courseid=C.courseid;
结果数据将具有与学生表完全相同的行数。结果集中将没有重复的studentid值(studentid被保留)。但是,尽管课程表中的课程ID是唯一的,但由于很多学生可能选择了同一门课程(因此,课程ID未保留),因此结果集中将重复该课程ID多次。
有了这个示例,您可以得出以下结论:
- 连接(studentid)后,基表中的每个键都充当结果数据的键
- 基本行中的行在结果数据中最多只出现一次。(无重复行)
这是密钥保留表的概念。
要了解视图列是否可更新,
select * from all_updatable_columns where table_name='V_VIEW_NAME';
PS:以大写字母提供表/视图名称。