原始出處: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是這樣的:
關鍵是一句話:一個數據只能出現一行(一次)。
新聞熱點
疑難解答