楼主: newkid

[每日一题] PL/SQL CHALLENGE 每日一题

[复制链接]
论坛徽章:
171
ITPUB社区OCM联盟徽章
日期:2013-07-30 11:25:46最佳人气徽章
日期:2013-03-19 17:13:45ITPUB年度最佳技术原创精华奖
日期:2013-03-22 13:18:30ITPUB季度 技术新星
日期:2012-05-22 15:10:11BLOG每日发帖之星
日期:2012-02-15 16:43:07生肖徽章2007版:马
日期:2012-03-07 10:13:26蓝锆石
日期:2012-02-24 10:13:15萤石
日期:2012-02-24 10:13:15海蓝宝石
日期:2012-02-24 10:13:15紫水晶
日期:2012-03-01 21:28:36
311#
发表于 2012-2-19 13:53 | 只看该作者
newkid 发表于 2012-2-16 01:01
2012-2-13 答案 ACD.
B,E: CONSTANT的值必须在声明的时候赋予,不可以在代码中赋值。
F: INITIALIZE 不是 ...

又学了一招

使用道具 举报

回复
论坛徽章:
171
ITPUB社区OCM联盟徽章
日期:2013-07-30 11:25:46最佳人气徽章
日期:2013-03-19 17:13:45ITPUB年度最佳技术原创精华奖
日期:2013-03-22 13:18:30ITPUB季度 技术新星
日期:2012-05-22 15:10:11BLOG每日发帖之星
日期:2012-02-15 16:43:07生肖徽章2007版:马
日期:2012-03-07 10:13:26蓝锆石
日期:2012-02-24 10:13:15萤石
日期:2012-02-24 10:13:15海蓝宝石
日期:2012-02-24 10:13:15紫水晶
日期:2012-03-01 21:28:36
312#
发表于 2012-2-19 14:33 | 只看该作者
newkid 发表于 2012-2-18 03:46
2012-2-15 答案 C.

A: varray不能用DELETE方法。你只能用TRIM方法从尾部删除数组元素。

显示5吗?我怎么感觉没答案了,测试一下

使用道具 举报

回复
论坛徽章:
171
ITPUB社区OCM联盟徽章
日期:2013-07-30 11:25:46最佳人气徽章
日期:2013-03-19 17:13:45ITPUB年度最佳技术原创精华奖
日期:2013-03-22 13:18:30ITPUB季度 技术新星
日期:2012-05-22 15:10:11BLOG每日发帖之星
日期:2012-02-15 16:43:07生肖徽章2007版:马
日期:2012-03-07 10:13:26蓝锆石
日期:2012-02-24 10:13:15萤石
日期:2012-02-24 10:13:15海蓝宝石
日期:2012-02-24 10:13:15紫水晶
日期:2012-03-01 21:28:36
313#
发表于 2012-2-19 14:41 | 只看该作者
newkid在多伦多是吧,我是说怎么总是这么晚都在了,时区原因啊

forall接触的少~望详解,测试的时候,发现执行了一次第二次受影响了,导致测试都没有结过 了

我估计a应该不对,b的精度也有些问题,e感觉也不对,
c应该是的

cd吧~

使用道具 举报

回复
论坛徽章:
520
奥运会纪念徽章:垒球
日期: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
314#
 楼主| 发表于 2012-2-22 03:06 | 只看该作者
2012-2-16 答案AD.
A: 正确,VALUES OF会先到l_indexes里面找数组元素的值(分别为2,3),然后用这个值作为l_ids的下标来代入到FORALL的DML。
B: 错误,VALUES OF会先到l_indexes里面找数组元素的值(分别为100,300),然后试图用这个值作为l_ids的下标来代入到FORALL的DML,而l_ids中并没有下标为100,300的元素。
   如果把VALUES OF修改为INDICES OF就正确了。
C: 错误,VALUES OF会先到l_indexes里面找数组元素的值(分别为2,3,3),然后用这个值作为l_ids的下标来代入到FORALL的DML, 可以看到下标为3出现了两次,则同一行会被UPDATE两次,employee_id=300的工资第一次被修改为2000000,第二次被修改为4000000。
D: 正确,类似A
F: 错误,VALUES OF所引用的数组必须为 INDEX BY BINARY_INTEGER或者INDEX BY PLS_INTEGER的associative array,嵌套表不被支持。
==============================================
2012-2-17 DBMS_OUTPUT.PUT_LINE的数据类型
作者:Steven Feuerstein
难度:低

我写了如下的不完整代码:
DECLARE
   /*DECLARE*/
BEGIN
   DBMS_OUTPUT.put_line (l_value);
END;

哪些选项可用来取代/*DECLARE*/注释从而使得这个代码块能够成功执行而不出错?

(A)
l_value   BOOLEAN := TRUE;

(B)
l_value   DATE := SYSDATE;

(C)
l_value   TIMESTAMP := SYSTIMESTAMP;

(D)
l_value   VARCHAR2(100) := 'Hurray!';

(E)
l_value   UTL_FILE.FILE_TYPE;

(F)
l_value   PLS_INTEGER := 100;

(G)
l_value   CHAR(1) := 'A';

使用道具 举报

回复
论坛徽章:
520
奥运会纪念徽章:垒球
日期: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
315#
 楼主| 发表于 2012-2-22 03:10 | 只看该作者
2012-2-20 日期运算
作者:Steven Feuerstein
难度:低

我需要写一个函数,它接受一个日期值(这个值永不为NULL),返回一个其值为第二天下午两点钟的日期型值。这是函数头:

CREATE OR REPLACE FUNCTION plch_tomorrow_at_2pm (
   date_in IN DATE)
   RETURN DATE
IS

(A)
BEGIN
   RETURN TO_DATE (
             TO_CHAR (date_in + 1, 'YYYY-MM-DD') || ' 14:00:00'
           ,  'YYYY-MM-DD HH24:MI:SS');
END;

(B)
BEGIN
   RETURN TRUNC (date_in + 1) + 14 / 24;
END;

(C)
BEGIN
   RETURN TRUNC (date_in + 1) + 2 / 24;
END;

(D)
BEGIN
   RETURN TRUNC (date_in) + 19/12;
END;

使用道具 举报

回复
论坛徽章:
520
奥运会纪念徽章:垒球
日期: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
316#
 楼主| 发表于 2012-2-23 03:45 | 只看该作者
2012-2-17 答案BCDFG

BOOLEAN,  UTL_FILE.FILE_TYPE 类型不能够用 DBMS_OUTPUT.PUT_LINE 输出。
==============================================

2012-2-20 答案ABD
C: 得到的时间是凌晨2点而不是下午2点。

==============================================
2012-2-21 INDEX BY数组用空串做下标
作者:Valentin Nikotin
难度:中

我把下列代码中的 /*CODE*/ 注释分别用选项中的代码取代:
declare
  type tbl_t is table of number index by varchar2(1);
  t tbl_t;
  c varchar2(1);
begin
  /*CODE*/
end;
/

哪些选项在执行的时候会抛出VALUE_ERROR异常?

(A)
t(c) := 1;

(B)
c := '';
t(c) := 1;

(C)
t('') := 1;

(D)
t(null) := 1;

(E)
select '' into c from dual;
t(c) := 1;

使用道具 举报

回复
论坛徽章:
520
奥运会纪念徽章:垒球
日期: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
317#
 楼主| 发表于 2012-2-24 02:57 | 只看该作者

2012-2-21 答案ADE

A: C未被初始化,因此为NULL, 当作为INDEX BY数组下标时会报VALUE_ERROR异常。
B: C被赋值为空串'', 在用作INDEX BY数组下标时ORACLE会认为它是有效下标,因此不会报错。注意这点与NULL的处理不同。
C: 同上,用的是 '' 做数组下标。
D: 同A, 用NULL做数组下标会报错。
E: 这又是一个陷阱,用SELECT INTO 会使C得到NULL, 而不同于B中用赋值语句得到的空串 '', 所以用作数组下标会报错。

知识点:
请记住 NULL 永远不会相等或不等于NULL (或其他任意东西)。如果你的表达式中有任意一个元素为NULL, 那么绝大多数情况下整个表达式的结果值也为NULL。

假如你需要NULL被另外处理,你必须写特定的逻辑,通常会设计到 NVL 函数(或者它的近亲:NVL2或COALESCE函数)或者用IS NULL/IS NOT NULL操作符。

一个长度为零的字符串(也被称为空串)是一个常量,由两个单引号构成,之间没有任何东西。在绝大多数情况下,ORACLE把长度为零的字符串和NULL值等同处理。

例如,下列代码在执行之后会显示"NULL!":

BEGIN
   IF '' IS NULL
   THEN
      DBMS_OUTPUT.put_line ('NULL!');
   END IF;
END;

然而,也存在某些情况,ORACLE会把长度为零的字符串作不同处理。

1.在用字符串作索引的数组(associative array)中,长度为零的字符串会被认为是一个有效的索引值,而NULL则会被拒绝。

2.有些 PL/SQL 的内置函数,当传递给它们的参数中有一个长度为零的字符串,其返回同样会是长度为零的字符串。这些函数包括NVL, COALESCE 和 TO_CHAR。你可以通过执行下列代码来验证这个现象;它不会抛出异常。

DECLARE
   TYPE tbl_t IS TABLE OF NUMBER INDEX BY VARCHAR2 (1);
   t   tbl_t;
BEGIN
   t (TO_CHAR ('')) := 1;
   t (NVL ('', '')) := 1;
   t (COALESCE ('', '')) := 1;
END;
/

3.把一个长度为零的字符串赋值给一个固定宽度的变量时,并不会把NULL值赋给该变量,如下所示:

SQL> declare
  2    c char(1);
  3  begin
  4    c := null;
  5    dbms_output.put_line('['||c||']');
  6    c := '';
  7    dbms_output.put_line('['||c||']');
  8  end;
  9  /

[]
[ ]

改变空串的处理方法:

在你的当前会话或者系统级执行如下语句,你就可以强迫PL/SQL把空串当作NULL来处理,如同在SQL中一样:

alter session [ or system ] set events '10932 trace name context forever, level 16384';

注意:你使用SET EVENTS时必须非常谨慎,它大部分用于DEBUG的目的,在产品应用中非常罕见(如果有的话)。


下面演示一下这个设置的影响:

Connected to:
Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options

SQL> create or replace procedure plch_proc as
  2    type tbl_t is table of number index by varchar2(1);
  3    t tbl_t;
  4  begin
  5    t('') := 1;
  6  end;
  7  /

Procedure created.

SQL> exec plch_proc

PL/SQL procedure successfully completed.

SQL> alter session set events '10932 trace name context forever, level 16384';

Session altered.

SQL> exec plch_proc

PL/SQL procedure successfully completed.

SQL> alter procedure plch_proc compile;

Procedure altered.

SQL> exec plch_proc
BEGIN plch_proc; END;

*
ERROR at line 1:
ORA-06502: PL/SQL: numeric or value error: NULL index table key value
ORA-06512: at "TEST_USER.PLCH_PROC", line 5
ORA-06512: at line 1

鸣谢:这个事件的设置和清除方法由_Nikotin提供。

使用道具 举报

回复
论坛徽章:
520
奥运会纪念徽章:垒球
日期: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
318#
 楼主| 发表于 2012-2-24 02:59 | 只看该作者
2012-2-22 DBMS_UTILITY.FORMAT_CALL_STACK
作者:Steven Feuerstein
难度:中

我在HR模式下创建了这个过程:

CREATE OR REPLACE PROCEDURE plch_show_cs (nth_in IN INTEGER)
IS
BEGIN
   IF nth_in <= 5
   THEN
      plch_show_cs (nth_in + 1);
   ELSE
      DBMS_OUTPUT.put_line (DBMS_UTILITY.format_call_stack);
   END IF;
END;
/

当我执行如下代码后,字符串"procedure HR.PLCH_SHOW_CS"在屏幕上会显示几次?

BEGIN
   plch_show_cs (1);
END;
/
(A)
0

(B)
1

(C)
5

(D)
6

使用道具 举报

回复
论坛徽章:
520
奥运会纪念徽章:垒球
日期: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
319#
 楼主| 发表于 2012-2-25 04:51 | 只看该作者
2012-2-22 答案D.

plch_show_cs 是个递归过程,出口是参数nth_in>6,plch_show_cs总共被调用了6次,最终DBMS_UTILITY.format_call_stack里面的内容是:

----- PL/SQL Call Stack -----
  object      line  object
  handle    number  name
B925DEA8         8  procedure HR.PLCH_SHOW_CS
B925DEA8         6  procedure HR.PLCH_SHOW_CS
B925DEA8         6  procedure HR.PLCH_SHOW_CS
B925DEA8         6  procedure HR.PLCH_SHOW_CS
B925DEA8         6  procedure HR.PLCH_SHOW_CS
B925DEA8         6  procedure HR.PLCH_SHOW_CS
B924A06C         2  anonymous block

使用道具 举报

回复
论坛徽章:
1
ITPUB十周年纪念徽章
日期:2011-11-01 16:26:29
320#
发表于 2012-2-28 17:26 | 只看该作者
本帖最后由 jgshdx305 于 2012-2-28 17:27 编辑

看到这些发现自己太水了

使用道具 举报

回复

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

本版积分规则 发表回复

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