原始出处:http://www.plsqlchallenge.com/作者: ChrisSaxon运行环境:SQLPLUS, SERVEROUTPUT已打开你正在创建一个应用来管理员工的项目。它会在如下的模式存储详细信息:create table plch_departments ( department_id int not null PRimary key, department_name varchar2(100) not null);create table plch_employees ( employee_id int not null primary key, employee_name varchar2(100) not null, department_id int not null references plch_departments ( department_id ));create table plch_employee_projects ( employee_id int not null references plch_employees ( employee_id ), project_id int not null, primary key ( employee_id, project_id ));insert into plch_departments values (1, 'Major department');commit;下列的哪些选项:创建了视图 plch_employees_v使得下列的插入语句执行不出错?insert into plch_employees_v ( employee_id, employee_name, department_id) values ( 1, 'Chris', 1);(A) create or replace view plch_employees_v as select emp.employee_id, emp.employee_name, emp.department_id from plch_employees emp;(B) create or replace view plch_employees_v as select emp.employee_id, emp.employee_name, emp.department_id from plch_employees emp join plch_departments dep on emp.department_id = dep.department_id;(C) create or replace view plch_employees_v as select emp.employee_id, emp.employee_name, emp.department_id, dep.department_name from plch_employees emp join plch_departments dep on emp.department_id = dep.department_id;(D) create or replace view plch_employees_v as select emp.employee_id, emp.employee_name, emp.department_id from plch_employees emp join plch_employee_projects epr on emp.employee_id = epr.employee_id;(E) create or replace view plch_employees_v as select emp.employee_id, emp.employee_name, emp.department_id, epr.project_id from plch_employees emp join plch_employee_projects epr on emp.employee_id = epr.employee_id;create or replace trigger plch_emp_iitinstead of insert on plch_employees_vbegin insert into plch_employees ( employee_id, employee_name, department_id ) values ( :new.employee_id, :new.employee_name, :new.department_id );end;/
A:(推荐)
这选项只选择了来自plch_employees的列。所以这个视图是“保键”的("key preserved")。查询没有函数或操作符,所以你能够插入数据。B: Plch_employees是plch_departments的子表。连接发生在plch_employees的主键。所以它是保键的。这意味着来自plch_employees的每一行数据在视图中最多出现一次。所以你可以往表中插入数据。C: 如同前一选项,plch_employees仍然是保键的。往视图中加上来自plch_departments的列也不会改变这一点。所以你仍然可以用这个视图向plch_employees插入数据。D: Plch_employee_projects是plch_employees的子表。连接上它就意味着当你查询视图的时候,一个employee的行可能出现多次。所以plch_employees不再是保键的。因此你在执行INSERT的时候会得到这个错误:"ORA-01779: cannot modify a column which maps to a non key-preserved table"E: instead of触发器会拦截视图上的DML操作。所以Oracle在视图中执行语句而不是在基表上执行。这解决了plch_employees的保键问题,插入可以成功执行。
这题做的有点累:首先去找保键:
没法子,去找instead of insert 触发器,结果找了一波08年10年的资料,上面说instead of 可以和替换的一起发生,并且可以写在表上,近几年更新,是替换而且只发生在视图上。
琢磨这句话E: instead of触发器会拦截视图上的DML操作。所以ORACLE在视图中执行语句而不是在基表上执行。这解决了plch_employees的保键问题,插入可以成功执行。
应该表述错了:instead of触发器会拦截视图上的DML操作。所以ORACLE在基表中执行语句而不是在视图上执行。这解决了plch_employees的保键问题(没有视图的事了),插入可以成功执行(插入到plch_employees,视图里没有)。
01779是这样的:
关键是一句话:一个数据只能出现一行(一次)。
新闻热点
疑难解答