有奖活动:PL/SQL Challenge 每日一题:2013-2-26 内置包DBMS_CQ_NOTIFICATION

[复制链接]
查看11 | 回复4 | 2008-9-15 01:28:12 | 显示全部楼层 |阅读模式
最先答对且答案未经编辑的puber将获得奥运章一枚(答案不可编辑但可发新贴补充或纠正),其他会员如果提供有价值的分析、讨论也可获得奥运章一枚。
以往旧题索引:
http://www.itpub.net/forum.php?m ... eid&typeid=1808
http://www.itpub.net/thread-1499223-1-1.html
原始出处:
http://www.plsqlchallenge.com/
作者:Viacheslav Stepanov
运行环境:SQLPLUS, SERVEROUTPUT已打开
注:本题给出答案时候要求给予简要说明才能得到奖品
我创建了几张表并填入数据:
CREATE TABLE plch_dept (dept_id NUMBER, dept_name VARCHAR2(30))
/
ALTER TABLE plch_dept
ADD CONSTRAINT plch_dept_pk PRIMARY KEY (dept_id)
/
CREATE TABLE plch_emp
(emp_id NUMBER, emp_name VARCHAR2(30), dept_id NUMBER)
/
ALTER TABLE plch_emp
ADD CONSTRAINT plch_emp_pk PRIMARY KEY (emp_id)
/
ALTER TABLE plch_emp
ADD CONSTRAINT emp_dept_fk FOREIGN KEY (dept_id)
REFERENCES plch_dept (dept_id)
/
BEGIN
INSERT INTO plch_dept VALUES (1, 'Sales');
INSERT INTO plch_dept VALUES (2, 'Marketing');
INSERT INTO plch_emp VALUES(1, 'John', 1);
INSERT INTO plch_emp VALUES(2, 'Jack', 1);
INSERT INTO plch_emp VALUES(3, 'Evlampiy', 2);
COMMIT;
END;
/
然后我创建了一个名为"PLCH_CALLBACK" 的过程来作为变更通知的回调过程。这个过程的实现细节不影响本题目的结果,所以没有提供。
哪些选项能够成功执行而不会引发未处理的异常?
假设本模式具备了这个题目所有操作所要求的权限。
(A)
DECLARE
v_cursor SYS_REFCURSOR;
regidNUMBER;
BEGIN
regid :=
DBMS_CQ_NOTIFICATION.new_reg_start (
cq_notification$_reg_info ('plch_callback',
DBMS_CQ_NOTIFICATION.QOS_QUERY, 0));
OPEN v_cursor FOR
SELECT emp_name FROM plch_emp e, plch_dept d
WHERE e.emp_name = 'Jack' or d.dept_id = 2;
CLOSE v_cursor;
DBMS_CQ_NOTIFICATION.reg_end;
END;
/

(B)
DECLARE
v_cursor SYS_REFCURSOR;
regidNUMBER;
BEGIN
regid :=
DBMS_CQ_NOTIFICATION.new_reg_start (
cq_notification$_reg_info ('plch_callback',
DBMS_CQ_NOTIFICATION.QOS_QUERY
+ DBMS_CQ_NOTIFICATION.QOS_BEST_EFFORT, 0));
OPEN v_cursor FOR
SELECT emp_name FROM plch_emp e
UNION ALL
SELECT dept_name FROM plch_dept d;
CLOSE v_cursor;
DBMS_CQ_NOTIFICATION.reg_end;
END;
/

(C)
DECLARE
v_cursor SYS_REFCURSOR;
regidNUMBER;
BEGIN
regid :=
DBMS_CQ_NOTIFICATION.new_reg_start (
cq_notification$_reg_info ('plch_callback',
DBMS_CQ_NOTIFICATION.QOS_QUERY, 0));
OPEN v_cursor FOR
SELECT e.emp_name, d.dept_name
FROM plch_emp e, plch_dept d
WHERE e.dept_id = d.dept_id;
CLOSE v_cursor;
DBMS_CQ_NOTIFICATION.reg_end;
END;
/

(D)
DECLARE
v_cursor SYS_REFCURSOR;
regidNUMBER;
BEGIN
regid :=
DBMS_CQ_NOTIFICATION.new_reg_start (
cq_notification$_reg_info ('plch_callback',
DBMS_CQ_NOTIFICATION.QOS_QUERY
+ DBMS_CQ_NOTIFICATION.QOS_BEST_EFFORT, 0));
OPEN v_cursor FOR
SELECT SUM(e.dept_id) FROM plch_emp e where e.dept_id = 1;
CLOSE v_cursor;
DBMS_CQ_NOTIFICATION.reg_end;
END;
/

(E)
DECLARE
v_cursor SYS_REFCURSOR;
regidNUMBER;
BEGIN
regid :=
DBMS_CQ_NOTIFICATION.new_reg_start (
cq_notification$_reg_info ('plch_callback',
DBMS_CQ_NOTIFICATION.QOS_QUERY, 0));
OPEN v_cursor FOR
SELECT SUBSTR(e.emp_name,1,2) FROM plch_emp e;
CLOSE v_cursor;
DBMS_CQ_NOTIFICATION.reg_end;
END;
/
(F)
DECLARE
v_cursor SYS_REFCURSOR;
regidNUMBER;
BEGIN
regid :=
DBMS_CQ_NOTIFICATION.new_reg_start (
cq_notification$_reg_info ('plch_callback',
DBMS_CQ_NOTIFICATION.QOS_QUERY
+ DBMS_CQ_NOTIFICATION.QOS_BEST_EFFORT, 0));
OPEN v_cursor FOR
SELECT d.dummy
FROM dual d;
CLOSE v_cursor;
DBMS_CQ_NOTIFICATION.reg_end;
END;
/


回复

使用道具 举报

千问 | 2008-9-15 01:28:12 | 显示全部楼层
跟游标的sql写法是有关系的,不太清楚,要出门送媳妇去机场,没时间细琢磨了


回复

使用道具 举报

千问 | 2008-9-15 01:28:12 | 显示全部楼层
答案:C, D, E
A, 以guaranteed模式注册,会产生ORA-29976: Unsupported query for registration in guaranteed mode错误。
B, 本选项会产生ORA-29983: Unsupported query for Continuous Query Notification错误,因为向QRCN注册的查询,只能是Best-Effort 模式
F,产生的错误与B相同,原因已经说明。

回复

使用道具 举报

千问 | 2008-9-15 01:28:12 | 显示全部楼层
截止至今日的每日一题奖励已发!请获奖的会员注意查收!!
感谢楼主的组织和大家的热情参与!


回复

使用道具 举报

千问 | 2008-9-15 01:28:12 | 显示全部楼层
答案CDE, 3楼得奖。
A: 在这个选项中,我们以保证模式注册,会得到这个错误:
ORA-29976: Unsupported query for registration in guaranteed mode
ORA-06512: at line 10
如果改用最佳效果模式则会成功。
B: 在这里我们得到如下错误:
ORA-29983: Unsupported query for Continuous Query Notification
ORA-06512: at line 11
另一方面,ORACLE的文档说带UNION ALL的查询能够以最佳效果模式注册:
哪些查询只能够以最佳效果模式注册QRCN(query result change notification, 查询结果变更通知):
满足任意下列条件之一的查询只能够以最佳效果模式注册QRCN,并且它的简化版本以对象级的粒度产生通知:
...
查询计划涉及任意以下之一:
Bitmap join, domain, 或者 function-based indexes
UNION ALL 或者 CONCATENATION (不管是在查询本身,或者优化器所选择的OR展开的执行计划)
C: 正确。等值连接不需要最佳效果模式。
"哪些查询能够以保证模式注册QRCN(query result change notification, 查询结果变更通知):
保证模式支持大部分单表查询,以及某些等值内连接。"
D: 这个查询太复杂了,不能够以保证模式注册。但是它能够以最佳效果模式注册QRCN, 在此情况下CQN会产生并注册一个简化版本(不带SUM)
如果不是最佳效果模式我们会得到一个错误:
ORA-29976: Unsupported query for registration in guaranteed mode
ORA-06512: at line 10
E: 在这选项中我们用到了SUBSTR函数。ORACLE文档说:它需要以最佳效果模式注册。
以下引用来自ORACLE文档:

哪些查询只能够以最佳效果模式注册QRCN(query result change notification, 查询结果变更通知):
满足任意下列条件之一的查询只能够以最佳效果模式注册QRCN,并且它的简化版本以对象级的粒度产生通知:
引用了加密的列;
在SELECT列表中有超过十个相同类型的项目;
具有包含任意以下之一的表达式:
字符串函数 (例如 SUBSTR, LTRIM, 和 RTRIM)
.....
看起来ORACLE文档需要一点小小的澄清。
实际上,在SELECT列表中带有字符串函数并不需要以最佳效果模式注册。
例如我们注册了这个查询:
OPEN v_cursor FOR
SELECT SUBSTR(e.emp_name,1,2) FROM plch_emp e
WHERE SUBSTR(e.emp_name,1,2) = 'a';
并且没有使用最佳效果模式,则会报错:
ORA-29976: Unsupported query for registration in guaranteed mode
ORA-06512: at line 11
不管怎么说,如果下列注册成功了:
仅仅在SELECT列表中包含SUBSTR(不在WHERE中),并且没有使用最佳效果模式
在WHERE中带有SUBSTR, 并且使用了最佳效果模式
那么查询将被以简化的格式注册,不带有SUBSTR, SUBSTR被移除了。并且在最佳效果模式中整个WHERE也被移除了。
F: 查询看起来似乎很简单,可是:
ORA-29983: Unsupported query for Continuous Query Notification
ORA-06512: at line 11
哪些查询不能够注册QRCN,不管是哪种模式:

如果一个查询引用了任意下列情况之一,则不能够注册QRCN,不管是保证模式或者最佳效果模式:
视图;
固定表(fixed tables, 即X$表),远程表,或者带有VPD(虚拟私有数据库)策略的表;
DUAL表(在SELECT列表中);
同义词;
调用了用户自定义的PL/SQL子程序;
在"能够以保证模式注册的查询"中列出来的操作符;
聚合函数COUNT(其他聚合函数在最佳效果模式下被允许,但不能用在保证模式)
实际上COUNT可以用在最佳效果模式(文档有误)
-------------------------------
DBMS_CQ_NOTIFICATION 包是数据库的变更通知功能的一部分,它提供了为客户应用指定的查询进行注册的功能,以便在查询所涉及的对象上发生了DML或者DDL变化时,能够收到通知。当DML或DDL事务被提交时,数据库就会发布这些通知。

如果一个查询注册了查询结果变更通知(QRCN),每当一个事务修改了查询结果并提交时,数据库就会通知应用程序。
缺省的通知类型是OCN(Object Change Notification, 对象变更通知)。对于QRCN, 在CQ_NOTIFICATION$_REG_INFO对象的QOSFLAGS指定QOS_QUERY。
对于QRCN, 你可以选择保证模式(缺省)或者最佳效果模式。
有时候最佳效果模式能够帮我们注册QRCN, 有时候不能。
QOS_BEST_EFFORT ---- 和 QOS_QUERY 一起使用。如果查询太复杂了,以至于无法对结果变更求值,它会注册查询的简化版本,换句话说,即以最佳效果模式注册QRCN,参见
http://docs.oracle.com/cd/E18283 ... ns_cqn.htm#CHDEJCJF
在这个题目中,最佳效果模式在D选项起了作用,它也可用作选项A, 但无法用在选项B和F。在选项C和E我们根本不需要最佳效果模式。
在最佳效果模式中,数据库将会把OLTP和通知处理相关的响应开销减到最低,如下:
对于单表查询,数据库根据哪些列被修改了,被改动的行满足了哪些谓词,从而决定查询结果是否被修改。
对于多表查询(表连接),数据库利用标间的主键/外键约束关系来决定查询结果是否变更。
每当一个DML语句修改了查询结果就送出一个QRCN通知,即使随后的DML低效了前面DML所做的修改。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

主题

0

回帖

4882万

积分

论坛元老

Rank: 8Rank: 8

积分
48824836
热门排行