一、相关方法
1.DECLARE_REWRITE_EQUIVALENCE 声明一个等价重写规则。
语法:
PROCEDURE DECLARE_REWRITE_EQUIVALENCE (
NAME VARCHAR(128),
SOURCE_STMT VARCHAR(8188),
DESTINATION_STMT VARCHAR(8188),
VALIDATE BOOLEAN,
REWRITE_MODE VARCHAR(16)
);
说明:
NAME 重写规则的唯一标识,在会话级唯一。
SOURCE_STMT 原始查询语句。
DESTINATION_STMT 目标语句。
VALIDATE 是否校验原始语句和目标语句等价。
REWRITE_MODE 包含4种:DISABLED,不允许重写;TEXT_MATCH,文本匹配重写;GENERAL,变换 重写; RECURSIVE,递归重写。后面两种暂不支持,可以声明成功,但是不起作用。
2. ALTER_REWRITE_EQUIVALENCE 修改重写模式。
语法:
PROCEDURE ALTER_REWRITE_EQUIVALENCE (
NAME CHAR(128),
REWRITE_MODE VARCHAR(16) );
3.VALIDATE_REWRITE_EQUIVALENCE 校验重写规则是否等效,暂不支持。提供该函数,但是不进行校验。
语法:
VALIDATE_REWRITE_EQUIVALENCE (
NAME CHAR(128) );
4.DROP_REWRITE_EQUIVALENCE 删除重写规则。
语法:
PROCEDURE DROP_REWRITE_EQUIVALENCE (
NAME CHAR(128) );
三、使用说明
1.设置会话标记
每个会话对应一个 QUERY_REWRITE_INTEGRITY 标记,只有在会话期间才有效,该标记不会写入字典,会话结束,该标记就无效了。
语法:ALTER SESSION SET QUERY_REWRITE_INTEGRITY = TRUSTED;
默认 值为“ENFORCED”,另外两个值为:“TRUSTED”和“STALE_TOLERATED”。
TRUSTED表示在保证物化视图数据是正确时才使用该视图替换。
STALE_TOLERATED表示能容忍错误的数据,即可以使用不正确的物化视图执行重写。
2.重写规则的作用域:只允许在当前会话,不能跨模式使用其他用户的重写规则,即使是SYSDBA,也不能使用其他用户的重写规则。
3.回滚:在执行方法 DECLARE_REWRITE_EQUIVALENCE后,自动提交,不能回滚。
4.自动重写
语法:
SP_USER_SET_AUTO_REWRITE_FLAG ( 'USER_NAME', VALUE );
USER_NAME用户名。
VALUE0表示不允许自动重写,1表示允许自动重写。
5.查询重写时机
①一般用户的查询;
②不是动态查询;
③视图中的查询重写,不支持递归替换。
6.关闭重用执行计划功能
使用时,可以在DM.INI中将重用执行计划标记(USE_PLN_POOL)置为 0。否则,先 执行过查询语句后,再设置查询规则,然后对比两次的查询结果会相同,即未被重写。如果 不关闭,只能等到设置过查询规则之后,才能执行查询。
7.测试用例
create table x1(id int,name varchar(20));
create table x2(id int,name varchar(20));
insert into x1 values(1,'aa');
insert into x1 values(2,'bb');
insert into x1 values(3,'cc');
insert into x2 values(1,'xx');
commit;
select SF_CHECK_SYSTEM_PACKAGES;
BEGIN
DBMS_ADVANCED_REWRITE.DECLARE_REWRITE_EQUIVALENCE(
'TEST_REWRITE',
'SELECT COUNT(*) FROM x1', --原始查询语句
'SELECT COUNT(*) FROM x2', --目标语句 FALSE,
'TEXT_MATCH' );
END;
SELECT COUNT(*) FROM x1; --
ALTER SESSION SET QUERY_REWRITE_INTEGRITY = TRUSTED;
SELECT COUNT(*) FROM x1;
DBMS_ADVANCED_REWRITE.DROP_REWRITE_EQUIVALENCE ('TEST_REWRITE'); --DROP REWRITE
BEGIN
DBMS_ADVANCED_REWRITE.DECLARE_REWRITE_EQUIVALENCE(
'TEST_REWRITE',
NULL, --为空
'FRO./FROM', --使用正则表达式 FALSE,
'TEXT_MATCH' );
END;
SELECT COUNT(*) FROK x1;