查看: 4300|回复: 5

[每日一题] 有奖活动:PL/SQL Challenge 每日一题:2012-8-2 在SQL中调用PLSQL函数

[复制链接]
论坛徽章:
533
奥运会纪念徽章:垒球
日期: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
发表于 2012-8-4 03:02 | 显示全部楼层 |阅读模式
有奖活动:PL/SQL Challenge 每日一题:2012-8-2 在SQL中调用PLSQL函数


最快答对且答案未经编辑的puber将获得奥运章一枚(编辑过的答案不算),其他会员如果提供有价值的分析、讨论也可获得奥运章一枚。

以往旧题索引:
http://www.itpub.net/thread-1499223-1-1.html

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

作者:Valentin Nikotin
难度:高

注:本题给出答案时候要求给予简要说明才能得到奖品

我创建了如下的数据库对象:
•一个包,带有一个全局变量
•一个函数,它将输入的变量返回,同时将全局变量增加1
•一个存储过程显示这个全局变量
•一个表,带有三行数据

create or replace package plch_cnt is
  g pls_integer;
end;
/

create or replace function plch_func (i number) return number is
begin
  plch_cnt.g := plch_cnt.g + 1;
  return i;
end;
/

create or replace procedure plch_show_cnt (i varchar2) is
begin
  dbms_output.put_line(i||' g = '||plch_cnt.g);
end;
/

create table plch_tbl (id number);

begin
  insert into plch_tbl values (1);
  insert into plch_tbl values (2);
  insert into plch_tbl values (3);
  commit;
end;
/
Then I write the following incomplete block:

declare
  val number;
  cursor cur is /*QUERY*/;
begin
  plch_cnt.g := 0;

  open cur;
  plch_show_cnt('after parse/execute');

  loop
    fetch cur into val;
    exit when cur%notfound;
    plch_show_cnt('after fetch');
  end loop;

  close cur;
end;
/

哪些选项用来取代/*QUERY*/ 注释之后,运行结果会显示如下文本?

after parse/execute g = 0
after fetch g = 1
after fetch g = 2
after fetch g = 3

(A)
select plch_func(id) val from plch_tbl


(B)
select plch_func(1) val from plch_tbl




(C)
select id val from plch_tbl where plch_func(id) = id


(D)
select id val from plch_tbl where plch_func(1) = 1

(E)
select plch_func(id) val from plch_tbl for update


(F)
select id val from plch_tbl where plch_func(id) = id for update
论坛徽章:
0
发表于 2012-8-6 13:55 | 显示全部楼层
答案:ABCEF
ABE 比较容易看出
C,D的区别是函数中是否含有字段,如果含有字段则会每行都执行一次,如果不含字段,则函数只执行一次。
F答案本来我以为是对的,可是测试发现是错的。这个可能需要高手讲解下。不明白。。。。

使用道具 举报

回复
论坛徽章:
6
奥运会纪念徽章:跳水
日期:2012-08-14 18:13:22奥运会纪念徽章:皮划艇激流回旋
日期:2012-08-14 18:13:32ITPUB 11周年纪念徽章
日期:2012-10-10 13:11:142013年新春福章
日期:2013-02-25 14:51:24奥运会纪念徽章:垒球
日期:2013-05-16 14:54:34奥运会纪念徽章:手球
日期:2013-05-16 14:54:49
发表于 2012-8-6 14:49 | 显示全部楼层
答案应该是:ABCE
这里有几个概念
1、包和包的全局变量,包是在会话第一次调用时加载至内存的,直到会话结束才释放,里面的全局变量是贯穿整个生命周期的。所以每调用函数一次就会增加变量。
2、SQL语句的分析,在Oracle执行语句之前,会首先对需要执行的语句进行语法分析,判断能否利用内存中已有的执行计划。
3、FOR UPDATE,使用此语句,会导致查询时给表的记录增加一条行锁定,可以通过此方式锁定某一行。

这样,D选项会因为进行语法分析时判断到plch_func(1)调用的参数是常量,每次调用结果都相同从而导致只需要一次调用。
而F选项因为 plch_func(id) 调用的参数是一个字段,同时因为有了For update语句,会在游标执行之前就进行锁定行的操作,从而后台会进行三次语法分析

使用道具 举报

回复
论坛徽章:
533
奥运会纪念徽章:垒球
日期: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
 楼主| 发表于 2012-8-7 04:57 | 显示全部楼层
答案ABCE, 3楼答对了。

注:SQL中调用PLSQL函数的次数、顺序都是不可控制的,应用逻辑不能对此有依赖。

D: ORACLE判断到WHERE里的函数结果和行数据无关,因此只会调用一次函数。
F: 在10G和11G下,本选项的执行结果:

Oracle Database 10g:

after parse/execute g = 3
after fetch g = 4
after fetch g = 5
after fetch g = 6

Oracle Database 11g:

after parse/execute g = 3
after fetch g = 3
after fetch g = 3
after fetch g = 3

貌似10G下有多余的执行。

使用道具 举报

回复
论坛徽章:
0
发表于 2012-8-7 12:04 | 显示全部楼层
F选项还是不清楚,能不能讲得详细点啊

使用道具 举报

回复
论坛徽章:
118
现任管理团队成员
日期:2011-05-07 01:45:08马上有钱
日期:2014-02-18 16:43:09马上有车
日期:2014-02-19 11:55:14马上有房
日期:2014-02-19 11:55:14马上有对象
日期:2014-02-19 11:55:14马上加薪
日期:2014-02-19 11:55:14ITPUB元老
日期:2014-03-05 22:46:57版主2段
日期:2014-03-27 02:21:00射手座
日期:2015-11-10 10:28:18
发表于 2012-8-14 18:13 | 显示全部楼层
奖励已发!!感谢楼主的组织,感谢大家的支持!!

使用道具 举报

回复

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

本版积分规则 发表回复

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