查看: 3121|回复: 1

[每日一题] PL/SQL Challenge 每日一题:2018-3-26 细粒度依赖关系

[复制链接]
论坛徽章:
526
奥运会纪念徽章:垒球
日期:2008-09-15 01:28:12生肖徽章2007版:鸡
日期:2008-11-17 23:40:58生肖徽章2007版:马
日期:2008-11-18 05:09:48数据库板块每日发贴之星
日期:2008-11-29 01:01:02数据库板块每日发贴之星
日期:2008-12-05 01:01:03生肖徽章2007版:虎
日期:2008-12-10 07:47:462009新春纪念徽章
日期:2009-01-04 14:52:28数据库板块每日发贴之星
日期:2009-02-08 01:01:03生肖徽章2007版:蛇
日期:2009-03-09 22:18:532009日食纪念
日期:2009-07-22 09:30:00
发表于 2018-4-3 07:46 | 显示全部楼层 |阅读模式

最先答对且答案未经编辑的puber将获得纪念章一枚(答案不可编辑但可发新贴补充或纠正),其他会员如果提供有价值的分析、讨论也可获得纪念章一枚。

每两周的优胜者可获得itpub奖励的技术图书一本。

以往旧题索引:
http://www.itpub.net/forum.php?m ... eid&typeid=1808

原始出处:
http://www.plsqlchallenge.com/

作者:Steven Feuerstein

运行环境:SQLPLUS, SERVEROUTPUT已打开
注:本题给出答案时候要求给予简要说明才能得到奖品

我执行了下列语句:


CREATE TABLE qz_table (n INTEGER, d DATE);

INSERT INTO qz_table (n, d) VALUES (1, SYSDATE);

CREATE TABLE qz_dates (nm VARCHAR2 (10), dt DATE);

CREATE OR REPLACE PROCEDURE qz_save_dates AUTHID DEFINER
IS
BEGIN
   DELETE FROM qz_dates;
   INSERT INTO qz_dates (nm, dt)
      SELECT object_name, last_ddl_time
        FROM user_objects
       WHERE object_name IN ('QZ_PROC1', 'QZ_PROC2', 'QZ_PROC3', 'QZ_PROC4')
         AND object_type = 'PROCEDURE';
   COMMIT;
END;
/

CREATE OR REPLACE PACKAGE qz_pkg AUTHID DEFINER IS
   PROCEDURE show_n (n_in IN NUMBER);
END;
/

CREATE OR REPLACE PACKAGE BODY qz_pkg IS
   PROCEDURE show_s (s_in IN VARCHAR2) IS
   BEGIN DBMS_OUTPUT.put_line (s_in); END;

   PROCEDURE show_n (n_in IN NUMBER) IS
   BEGIN show_s ('n = ' || n_in); END;
END;
/

CREATE OR REPLACE PROCEDURE qz_proc1 (n_in IN NUMBER) AUTHID DEFINER
IS
   r qz_table%ROWTYPE;
BEGIN
   SELECT t.n, t.d INTO r FROM qz_table t WHERE t.n = qz_proc1.n_in;
   qz_pkg.show_n (n_in => r.n);
END;
/

CREATE OR REPLACE PROCEDURE qz_proc2 (n_in IN NUMBER) AUTHID DEFINER
IS
   TYPE rt IS RECORD (n NUMBER, d DATE);
   r rt;
BEGIN
   SELECT t.n, t.d INTO r FROM qz_table t WHERE t.n = qz_proc2.n_in;
   qz_pkg.show_n (n_in => r.n);
END;
/

CREATE OR REPLACE PROCEDURE qz_proc3 (n_in IN qz_table.n%TYPE) AUTHID DEFINER
IS
   TYPE rt IS RECORD (n qz_table.n%TYPE, d qz_table.d%TYPE);
   r rt;
BEGIN
   SELECT t.n, t.d INTO r FROM qz_table t WHERE t.n = qz_proc3.n_in;
   qz_pkg.show_n (n_in => r.n);
END;
/

CREATE OR REPLACE PROCEDURE qz_proc4 (n_in IN NUMBER) AUTHID DEFINER
IS
   r qz_table%ROWTYPE;
BEGIN
   SELECT * INTO r FROM qz_table t WHERE t.n = qz_proc4.n_in;
   qz_pkg.show_n (n_in => r.n);
END;
/

BEGIN qz_save_dates; END;
/

哪些选项可以用来取代下列代码中的 ##REPLACE## :

BEGIN
   DBMS_LOCK.sleep (2);
   ##REPLACE##
EXCEPTION
   WHEN OTHERS
   THEN
      DBMS_OUTPUT.PUT_LINE (DBMS_UTILITY.FORMAT_ERROR_STACK);
END;
/

使得下列语句执行之后会显示 "COUNT = 0" ?

DECLARE
   PROCEDURE runit (n_in IN INTEGER)
   IS
   BEGIN
      EXECUTE IMMEDIATE 'begin qz_proc' || n_in || '(1); end;';
   EXCEPTION
      WHEN OTHERS
      THEN
         NULL;
   END;
BEGIN
   runit (1);
   runit (2);
   runit (3);
   runit (4);
END;
/

SELECT 'COUNT = ' || COUNT (*) the_count
  FROM user_objects uo, qz_dates dt
WHERE uo.object_name = dt.nm
   AND uo.last_ddl_time > dt.dt
/


(A)
EXECUTE IMMEDIATE 'ALTER TABLE qz_table ADD var VARCHAR2(100)';

(B)
EXECUTE IMMEDIATE 'ALTER TABLE qz_table DROP COLUMN dt';

(C)
EXECUTE IMMEDIATE 'ALTER TABLE qz_table MODIFY n NUMBER';

(D)
EXECUTE IMMEDIATE 'CREATE INDEX i_qz_table ON qz_table (n)';

(E)
EXECUTE IMMEDIATE 'ALTER TABLE qz_table ADD n VARCHAR2(100)';

(F)
EXECUTE IMMEDIATE 'DROP TABLE qz_table';

(G)
EXECUTE IMMEDIATE 'ALTER PACKAGE qz_pkg COMPILE';

(H)
EXECUTE IMMEDIATE 'CREATE OR REPLACE PACKAGE qz_pkg AUTHID DEFINER
IS
   SUBTYPE new_type_t IS NUMBER;
   PROCEDURE show_n (n_in IN NUMBER);
END;';


(I)
EXECUTE IMMEDIATE 'CREATE OR REPLACE PACKAGE qz_pkg AUTHID DEFINER
IS
   PROCEDURE show_s (s_in IN VARCHAR2);
   PROCEDURE show_n (n_in IN NUMBER);
END;';

(J)
EXECUTE IMMEDIATE 'CREATE OR REPLACE PACKAGE qz_pkg AUTHID DEFINER
IS
   PROCEDURE show_n (n_in IN NUMBER);
   PROCEDURE show_s (s_in IN VARCHAR2);
END;';
论坛徽章:
526
奥运会纪念徽章:垒球
日期:2008-09-15 01:28:12生肖徽章2007版:鸡
日期:2008-11-17 23:40:58生肖徽章2007版:马
日期:2008-11-18 05:09:48数据库板块每日发贴之星
日期:2008-11-29 01:01:02数据库板块每日发贴之星
日期:2008-12-05 01:01:03生肖徽章2007版:虎
日期:2008-12-10 07:47:462009新春纪念徽章
日期:2009-01-04 14:52:28数据库板块每日发贴之星
日期:2009-02-08 01:01:03生肖徽章2007版:蛇
日期:2009-03-09 22:18:532009日食纪念
日期:2009-07-22 09:30:00
 楼主| 发表于 2018-4-4 04:11 | 显示全部楼层
答案BDEGHJ, 本期无人参与。

A: 这个选项显示"COUNT = 2", 这意味着两个过程失效了并且在匿名块执行之前被重新编译。我增加了一个列,那么为什么会使得过程失效呢?无论如何,它们不可能用到这个列。

但是两个过程利用了“捷径”来指定“表中的所有列”:

qz_proc1 用了 %ROWTYPE.

qz_proc4 用了 "SELECT *".

结果,即使你只是增加了一个列,这些程序会被标识为无效,并且需要重编译。

B: 并不存在一个名为"DT" 的列,所以对表不会有任何修改,所以就不会有失效的连锁反应。
C: 我将一个列的数据类型从INTEGER 改成 NUMBER。这会导致任何引用这个列的程序单元失效。本例中的所有过程都被影响,所以"COUNT = 4" 会被显示。
D: 增加一个索引不会像表那样对程序单元的依赖性产生影响,所以什么也不会失效。
E: 已经存在这个名字的列,所以对表不会有任何修改,所有程序单元的状态仍然照旧。"COUNT = 0" 被显示。
F: 删了整个表?天哪。这当然会使得所有引用到这个表的程序单元失效。 "COUNT = 4" 会被显示。
G: 我请求重编译这个包,这当然会修改最后改动的时间戳,但是PL/SQL编译器很聪明地注意到了包中什么也没改变,所以任何程序单元的状态都不会改变,也不会发生重编译。
H: 现在,当我重新编译这个包,它里面有了两个新的子类型,但是没有一个现存的程序单元可能会依赖于这个新类型,所以这些过程都不会失效。
I: 我将show_s暴露在包头里面,但是处于show_n之上。这会使得show_n的“入口点编号”发生变化,于是把过程强制失效了。
J: 我将show_s暴露在包头里面,但是放在show_n后面。这意味着show_n的“入口点编号”没有发生变化,于是也不会发生失效。

使用道具 举报

回复

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

本版积分规则 发表回复

TOP技术积分榜 社区积分榜 徽章 团队 统计 知识索引树 积分竞拍 文本模式 帮助
  ITPUB首页 | ITPUB论坛 | 数据库技术 | 企业信息化 | 开发技术 | 微软技术 | 软件工程与项目管理 | IBM技术园地 | 行业纵向讨论 | IT招聘 | IT文档
  ChinaUnix | ChinaUnix博客 | ChinaUnix论坛
CopyRight 1999-2011 itpub.net All Right Reserved. 北京盛拓优讯信息技术有限公司版权所有 联系我们 
京ICP备16024965号 北京市公安局海淀分局网监中心备案编号:11010802021510 广播电视节目制作经营许可证:编号(京)字第1149号
  
快速回复 返回顶部 返回列表