PL/SQL Challenge 每周一题:2021-11-13 定义子类型

[复制链接]
查看11 | 回复1 | 2008-9-15 01:28:12 | 显示全部楼层 |阅读模式
最先答对且答案未经编辑的puber将获得纪念章一枚(答案不可编辑但可发新贴补充或纠正),其他会员如果提供有价值的分析、讨论也可获得纪念章一枚。
每两周的优胜者可获得itpub奖励的技术图书一本。
以往旧题索引:
http://www.itpub.net/forum.php?m ... eid&typeid=1808
原始出处:
https://devgym.oracle.com/
作者:Kim Berg Hansen
运行环境:SQLPLUS, SERVEROUTPUT已打开, 最低版本要求:11.2
注:本题给出答案时候要求给予简要说明才能得到奖品
我有一张表,有一个列的精度和宽度都受了约束,所以它最多能够包含3位数字:
create table qz_numbers (
id integer primary key
, valuenumber(3, 0)
);
下面的每个选项包含了一个匿名块,它们用不同的方式定义了一个变量然后位该变量赋值。
哪些选项能够成功执行不出错?

(A)
declare
v_valueqz_numbers.value%TYPE;
begin
v_value := 42;
end;
/

(B)
declare
v_valueqz_numbers.value%TYPE;
begin
v_value := 4200;
end;
/
(C)
declare
subtypesmallint is number(3, 0);
v_valuesmallint;
begin
v_value := 42;
end;
/
(D)
declare
subtypesmallint is number(3, 0);
v_valuesmallint;
begin
v_value := 4200;
end;
/
(E)
declare
subtypesmallint is qz_numbers.value%TYPE;
v_valuesmallint;
begin
v_value := 42;
end;
/
(F)
declare
subtypesmallint is qz_numbers.value%TYPE;
v_valuesmallint;
begin
v_value := 4200;
end;
/
(G)
declare
subtypesmallint is qz_numbers.value%TYPE;
subtypemediumint is smallint(6, 0);
v_valuemediumint;
begin
v_value := 42;
end;
/
(H)
declare
subtypesmallint is qz_numbers.value%TYPE;
subtypemediumint is smallint(6, 0);
v_valuemediumint;
begin
v_value := 4200;
end;
/

(I)
declare
subtypemediumint is qz_numbers.value%TYPE(6, 0);
v_valuemediumint;
begin
v_value := 42;
end;
/
(J)
declare
subtypemediumint is qz_numbers.value%TYPE(6, 0);
v_valuemediumint;
begin
v_value := 4200;
end;
/

回复

使用道具 举报

千问 | 2008-9-15 01:28:12 | 显示全部楼层
答案ACEGH,本期无人参与。
A:
变量和列数据类型进行了锚定,所以它就是NUMBER(3, 0), 可以包含42, 没任何问题。
B:
变量和列数据类型进行了锚定,所以它就是NUMBER(3, 0), 这不能包含4200, 所以会报错:
ORA-06502: PL/SQL: numeric or value error: number precision too large.
C:
我们定义了一个子类型为NUMBER(3, 0), 可以包含42, 没任何问题。
D:
但是定义的smallint子类型不能包含4200,所以会报错:
ORA-06502: PL/SQL: numeric or value error: number precision too large.
E:
子类型可以用列锚定类型来定义,列上的约束被继承,所以SMALLINT就是NUMBER(3, 0), 可以轻易地包含42。
F:
如同前面所见,既然约束从表的列被继承到子类型,SMALLINT无法包含4200,会报错:
ORA-06502: PL/SQL: numeric or value error: number precision too large.
G:
我们可以通过定义一个新的子类型MEDIUMINT,指定更大的精度,从而覆盖子类型上的精度和宽度约束,
H:
利用这个覆盖了精度的子类型MEDIUMINT我们可以存储值4200,不会报错。
I:
在前两个选项中,我们创建了子类型MEDIUMINT,覆盖了子类型SMALLINT上的精度宽度约束,这是没问题的。但是我们不能直接覆盖用%TYPE的列锚定类型上的约束,这是非法的,会报错:
PLS-00573: cannot constrain scale, precision, or range of an anchored type declaration
J:
因为这是一个编译错误,本选项和前一选项都报同样的错:
(PLS-00573: cannot constrain scale, precision, or range of an anchored type declaration)
我们试图赋予什么值都无关紧要,因为我们永远执行不到赋值语句。
回复

使用道具 举报

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

本版积分规则

主题

0

回帖

4882万

积分

论坛元老

Rank: 8Rank: 8

积分
48824836
热门排行