Mastering Oracle SQL学习笔记(join句法专题第八部份)

用数据字典视图获得可更新的列
 
Oracle 提供了一种数据字典视图 USER_UPDATABLE_COLUMNS 它可列出用户定义的表或视图中可以被修改的所有列。这对我们是非常有用的:当你有一个视图你想对其进行更新操作,但是你又不确定哪些列是可以更新的,可时你就可以用数据字典视图 USER_UPDATABLE_COLUMNS
DESC USER_UPDATABLE_COLUMNS
 
 
 
 Name           Null?    Type
 
 -------------- -------- -------------
 
 OWNER          NOT NULL VARCHAR2(30)
 
 TABLE_NAME     NOT NULL VARCHAR2(30)
 
 COLUMN_NAME    NOT NULL VARCHAR2(30)
 
 UPDATABLE               VARCHAR2(3)
 
 INSERTABLE              VARCHAR2(3)
 
 DELETABLE               VARCHAR2(3)
 
看一个例子:
 
SELECT * FROM USER_UPDATABLE_COLUMNS
 
WHERE TABLE_NAME = 'V_RTLR_EMP';
 
 
 
OWNER   TABLE_NAME    COLUMN_NAME      UPD INS DEL
 
------- ------------- ---------------- --- ---
 
DEMO    V_RTLR_EMP    RTLR_NBR         YES YES YES
 
DEMO    V_RTLR_EMP    NAME             YES YES YES
 
DEMO    V_RTLR_EMP    CITY             YES YES YES
 
DEMO    V_RTLR_EMP    EMP_ID           NO  NO  NO
 
DEMO    V_RTLR_EMP    SALESPERSON_ID   YES YES YES
 
DEMO    V_RTLR_EMP    SALES_REP        NO  NO  NO
 
除此之外还有 ALL_UPDATABLE_COLUMNS 可以列出所有你可以访问的视图的可编辑列, DBA_UPDATABLE_COLUMNS( 只有 DBA 可以使用 ) 可以列出数据库中所有视图的可编辑列。
 
 
2.7.1 WITH CHECK OPTION 的影响
 
WITH CHECK OPTION 是创建视图指令的一个选项指令,它可以防止你对不存在于视图中的数据做任何更新。举例,如果你有一个视图像下面的定义:
CREATE VIEW emp_20 AS
 
SELECT * FROM employee
 
WHERE dept_id = 20
 
WITH CHECK OPTION;
 
对这个视图进行作操时,你不能插入 dept_id=30 的行 , 也不能把已经存在的行的 dept_id 更新成 30;
 
INSERT INTO emp_20 VALUES
 
(8765, 'SANJAY','MISHRA', 30, 7656, 4000, '01-JAN-88', 765);
 
INSERT INTO emp_20 VALUES
 
            *
 
ERROR at line 1:
 
ORA-01402: view WITH CHECK OPTION where-clause violation
 
 
 
UPDATE emp_20 SET dept_id = 30;
 
UPDATE emp_20 SET dept_id = 30
 
       *
 
ERROR at line 1:
 
ORA-01402: view WITH CHECK OPTION where-clause violation
 
因为被 WITH CHECK OPTION 定义的视图 而这个视图 emp_20 中只有 dept_id=20 的数据 , 所以不允许对此视图中不存在的数据进行更新 !
 
如果连接视图 (join view) 创建时使用了 WITH CHECK OPTION 定义 , 则该连接视图不允许插入操作 , 即使你是对键保护 ( key-preserved) 表进行插入 :
CREATE VIEW v_rtlr_emp_wco AS
 
SELECT c.rtlr_nbr, c.name, c.city, c.salesperson_id, e.lname sales_rep
 
FROM retailer c JOIN employee e
 
ON c.salesperson_id = e.emp_id
 
WITH CHECK OPTION;
 
 
 
View created.
 
 
 
INSERT INTO v_rtlr_emp_wco (rtlr_nbr, name, salesperson_id)
 
VALUES (345, 'X-MART STORES', 7820);
 
INSERT INTO v_rtlr_emp_wco (rtlr_nbr, name, salesperson_id)
 
                            *
 
ERROR at line 1:
 
ORA-01733: virtual column not allowed here
 
 
WITH CHECK OPTION 对于连接视图的删除操作不保护 :
 
DELETE FROM v_rtlr_emp_wco
 
WHERE rtlr_nbr = 215;
 
1 row deleted.
 
然而如果你的连接视图中是自我连接 (self join) 的键保护 ( key-preserved) , 则不能删除 :
 
CREATE VIEW emp_mgr_wco AS
 
SELECT e.lname employee, e.salary salary, m.lname manager
 
FROM employee e, employee m
 
WHERE e.manager_emp_id = m.emp_id
 
WITH CHECK OPTION;
 
 
 
View created.
 
 
 
DELETE FROM emp_mgr_wco WHERE employee = 'JONES';
 
DELETE FROM emp_mgr_wco WHERE employee = 'JONES'
 
            *
 
ERROR at line 1:
 
ORA-01752: cannot delete from view without exactly one key-preserved table
 
如果一个连接视图创建时使用了 WITH CHECK OPTION 刚你不可以对视图中的任何列进行修改 :
 
UPDATE v_rtlr_emp_wco
 
SET salesperson_id = 7784
 
WHERE rtlr_nbr = 215;
 
SET salesperson_id = 7784
 
    *
 
ERROR at line 2:
 
ORA-01733: virtual column not allowed here
 
在上面的例子上 , 显然是报错了 , 同样在自我连接 (self join) 的键保护 ( key-preserved) 表创建的视图中使用更新操作会得到同样的错误 :
 
UPDATE emp_mgr_wco
 
SET salary = 4800
 
WHERE employee = 'JONES';
 
SET salary = 4800
 
    *
 
ERROR at line 2:
 
ORA-01733: virtual column not allowed here

你可能感兴趣的:(oracle,数据库,职场,休闲)