查看: 279|回复: 2

[每日一题] PL/SQL Challenge 每日一题:2020-10-1 检查约束

[复制链接]
论坛徽章:
527
奥运会纪念徽章:垒球
日期: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
发表于 2020-10-13 22:35 | 显示全部楼层 |阅读模式
最先答对且答案未经编辑的puber将获得纪念章一枚(答案不可编辑但可发新贴补充或纠正),其他会员如果提供有价值的分析、讨论也可获得纪念章一枚。

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

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

原始出处:
https://devgym.oracle.com/

作者:Chris Saxon

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

你创建了这张表来存储棋盘的信息:

create table qz_chessboard (
  file_value varchar2(1)
    not null,
  rank_value integer
    not null,
  colour     varchar2(10)
    check ( colour in ( 'black', 'white' ) )
    not null,
  primary key (
    file_value, rank_value
  )
);

哪些选项实现了这样的约束:

FILE_VALUE 为小写字母 a, b, c, d, e, f, g, 以及 h
RANK_VALUE 只能为数值 1, 2, 3, 4, 5, 6, 7, 以及 8

在一个成功的选项执行之后,前两个INSERT必须成功,剩下三个必须报错ORA-02290:

insert into qz_chessboard
  values ( 'a', 1, 'black' );
insert into qz_chessboard
  values ( 'h', 1, 'white' );

/* 大写 */
insert into qz_chessboard
  values ( 'A', 8, 'black' );
/* file_value 越界 */
insert into qz_chessboard
  values ( 'i', 8, 'white' );
/* rank_value 越界 */
insert into qz_chessboard
  values ( 'a', 9, 'black' );

(A)
alter table qz_chessboard
  add constraint qz_ches_rank_file_value_c
  check (
    file_value between 'a' and 'h' and
    rank_value between 1 and 8
  );

(B)
alter table qz_chessboard
  add constraint qz_ches_rank_file_value_c
  check (
    regexp_like (
      file_value || rank_value, '[a-h][1-8]'
    )
  );

(C)
alter table qz_chessboard
  add constraint qz_ches_rank_file_value_c
  check (
    file_value || rank_value between 'a1' and 'h8'
  );

(D)
alter table qz_chessboard
  add constraint qz_ches_rank_file_value_c
  check (
    rank_value + ascii ( file_value ) between 98 and 112
  );

(E)
alter table qz_chessboard
  add constraint qz_ches_file_value_c
  check ( file_value between 'a' and 'h' );
alter table qz_chessboard
  add constraint qz_ches_rank_value_c
  check ( rank_value between 1 and 8 );

论坛徽章:
536
生肖徽章2007版:猴
日期:2008-05-16 11:28:59生肖徽章2007版:马
日期:2008-10-08 17:01:01SQL大赛参与纪念
日期:2011-04-13 12:08:17授权会员
日期:2011-06-17 16:14:53ITPUB元老
日期:2011-06-21 11:47:01ITPUB官方微博粉丝徽章
日期:2011-07-01 09:45:27ITPUB十周年纪念徽章
日期:2011-09-27 16:30:472012新春纪念徽章
日期:2012-01-04 11:51:22海蓝宝石
日期:2012-02-20 19:24:27铁扇公主
日期:2012-02-21 15:03:13
发表于 2020-10-14 09:45 | 显示全部楼层

  
答案:ABE
A: 将两个字段的枚举值约束范围定义在一个表级约束中,AND同时满足
B: 两个字段作字符拼接在一起,并用正则表达式控制字符范围
C: 同样是拼接,但between and 的控制中,a1-a9,...到 h8 这范围过大
D: 数字1-8 加 ascii('a') - ascii('h')  大概范围是1+97 - 8+104, 但 9+97=106,也在这个范围,
   一个更小的值加一个更大一点的值都可以在这个范围,所以这样的控制方法并不保险
E: 两个字段分别定义各自字段级别的约束,传统,简单,保险

使用道具 举报

回复
论坛徽章:
527
奥运会纪念徽章:垒球
日期: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
 楼主| 发表于 2020-10-14 22:18 | 显示全部楼层
答案ABE, 2楼得奖。

A:
这将在一个约束下执行两个规则。

B:
使用正则表达式来验证值是a1 ... h8,字母在a和h之间,数字是1至8。

C:
这与前一个选项类似,但只检查连接的值是否在a1 ... h8范围内。虽然这只允许直线的值在a和h之间,但你可以存储横线越界值。例如a9,bB,c#等。

D:
小写字母a的ASCII值是97。所以ASCII ('a') + 1 = 98,ASCII ('h') + 8 = 112。但与前一选项类似,这可以让你存储越界值。此时直线和横线可能同时越界,例如ASCII ('@') + 34 = 98。

E:
这和A选项的逻辑是一样的,只是分为两个约束条件。

使用道具 举报

回复

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

本版积分规则 发表回复

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