下面的例子将演示如何联机重定义使用VPD策略的表。这个例将禁用所有的触发器而不修改表的列名或数据类型。原始表jy.employees的创建语句如下:
SQL> create table jy.employees( 2 employee_id number(6) primary key, 3 first_name varchar2(20), 4 last_name varchar2(25) 5 constraint emp_last_name_nn not null, 6 email varchar2(25) constraint emp_email_nn not null, 7 phone_number varchar2(20), 8 hire_date date constraint emp_hire_date_nn not null, 9 job_id varchar2(10) constraint emp_job_nn not null, 10 salary number(8,2), 11 commission_pct number(2,2), 12 manager_id number(6), 13 department_id number(4), 14 constraint emp_salary_min check (salary > 0), 15 constraint emp_email_uk unique (email) 16 ); Table created.
使用下面的jy.auth_emp_dep_100函数来创建VPD策略
SQL> create or replace function jy.auth_emp_dep_100( 2 schema_var in varchar2, 3 table_var in varchar2 4 ) 5 return varchar2 6 as 7 return_val varchar2 (400); 8 unm varchar2(30); 9 begin 10 select user into unm from dual; 11 if (unm = 'jy') then 12 return_val := null; 13 else 14 return_val := 'department_id = 100'; 15 end if; 16 return return_val; 17 end auth_emp_dep_100; 18 / Function created.
执行dbms_rls_add_policy过程来对原始表jy.employees表使用jy.auth_emp_dep_100函数来指定VPD策略
SQL> begin 2 dbms_rls.add_policy( 3 object_schema => 'jy', 4 object_name => 'employees', 5 policy_name => 'employees_policy', 6 function_schema => 'jy', 7 policy_function => 'auth_emp_dep_100'); 8 end; 9 / PL/SQL procedure successfully completed.
在这个例子中,表jy.employees表重定义后将会禁用所有的触发器。注意重定义将不会修改列名或数据类型。因此在执行start_refef_table过程时copy_vpd_opt参数设置为dbms_redefinition.cons_vpd_auto。
1.用要执行联机重定义操作的用户登录数据库
SQL> conn jy/jy@jypdb Connected.
2.验证原始表是否可以执行联机重定义
SQL> begin 2 dbms_redefinition.can_redef_table('hr','employees',DBMS_REDEFINITION.CONS_USE_PK); 3 end; 4 / PL/SQL procedure successfully completed.
3.创建中间表jy.int_employees
SQL> create table jy.int_employees( 2 employee_id number(6), 3 first_name varchar2(20), 4 last_name varchar2(25), 5 email varchar2(25), 6 phone_number varchar2(20), 7 hire_date date, 8 job_id varchar2(10), 9 salary number(8,2), 10 commission_pct number(2,2), 11 manager_id number(6), 12 department_id number(4)); Table created.
4.开始联机重定义操作
SQL> begin 2 dbms_redefinition.start_redef_table( 3 uname => 'jy', 4 orig_table => 'employees', 5 int_table => 'int_employees', 6 col_mapping => NULL, 7 options_flag => DBMS_REDEFINITION.CONS_USE_PK, 8 orderby_cols => NULL, 9 part_name => NULL, 10 copy_vpd_opt => DBMS_REDEFINITION.CONS_VPD_AUTO); 11 end; 12 / PL/SQL procedure successfully completed.
当copy_vpd_opt参数被设置为dbms_redefinition.cons_vpd_auto时,只有表的所有者与调用联机重定义操作的用户可以在联机重定义期间访问该表。col_mapping参数设置为NULL。当copy_vpd_opt参数设置为dbms_redefinition.cons_vpd_auto时,col_mapping参数必须设置为NULL或’*’。
5.复制依赖对象
SQL> declare 2 num_errors pls_integer; 3 begin 4 dbms_redefinition.copy_table_dependents( 5 uname => 'jy', 6 orig_table => 'employees', 7 int_table => 'int_employees', 8 copy_indexes => DBMS_REDEFINITION.CONS_ORIG_PARAMS, 9 copy_triggers => TRUE, 10 copy_constraints => TRUE, 11 copy_privileges => TRUE, 12 ignore_errors => FALSE, 13 num_errors => num_errors); 14 end; 15 / PL/SQL procedure successfully completed.
6.对中间表禁用所有的触发器
SQL> alter table jy.int_employees disable all triggers; Table altered.
7.可选操作同步中间表
SQL> begin 2 dbms_redefinition.sync_interim_table( 3 uname => 'jy', 4 orig_table => 'employees', 5 int_table => 'int_employees'); 6 end; 7 / PL/SQL procedure successfully completed.
8.完成联机重定义操作
SQL> begin 2 dbms_redefinition.finish_redef_table( 3 uname => 'jy', 4 orig_table => 'employees', 5 int_table => 'int_employees'); 6 end; 7 / PL/SQL procedure successfully completed.
9.等待任何查询中间表的语句执行完成后将其删除
SQL> drop table jy.int_employees; Table dropped
到此重定义操作就完成了。