第 一 章
一、你服务的公司要建立一个网络论坛,考虑创建一个存储用户基本信息的表,表名为User_info,包括用户ID、妮称、密码、Email、所在地区、注册日期、用户分数、发帖数。
二、上面的创建表命令是DDL还是DML命令,DDL和DML分别代表什么
三、显示发帖数超过十万的用户的ID
四、显示注册日期在一年以内,发帖数过万的会员ID
五、按用户分数列,由大到小显示分数超过1000分的会员ID、妮称,对于分数相同的会员,按发帖数量由大到小显示。
六、为所有发帖数超过1万的会员用户分数加50分
七、为此用户基本信息表添加一个用户等级列,并按如下规则设置每个会员的等级:
初级会员:注册日期在三个月内并且发帖数在100以内的
中级会员:注册日期在一年以内并且发帖数在300以内的
高级会员:注册日期在二年以内并且发帖数在1000以内的
老会员:注册日期在四年以内并且发帖数在3000以内的
骨灰会员:发帖数在8000以内的。
管理员:发帖数在1万以内
超级管理员:发帖数在5万以内
八、ID为“AAA”的违返了论坛规则,删除此ID
九、显示妮称中包含“奥运”字样会员的ID、妮称
十、显示有哪些地区的会员发帖数量在10000以上
答案
三:select 用户ID from user_info where 发帖数>=100000;
四:select 用户ID from user_info where 发帖数>=10000 and 注册日期>=to_date(‘2007-09-08’,’yyyy-mm-dd’);
五:select 用户ID,妮称 from user_info order by 用户分数,发帖数量;
六:update user_info set 用户分数=用户分数+50 where 发帖数>=10000;
七:alter user_info add 等级 varchar2(14);
update user_info set 等级=’初级会员’ where 注册日期>=to_date(‘2008-6-7’) and 发帖数<=100;
update user_info set 等级=’中级会员’ where 注册日期>=to_date(‘2007-9-7’) and 发帖数<=300;
update user_info set 等级=’高级会员’ where 注册日期>=to_date(‘2006-9-7’) and 发帖数<=1000;
update user_info set 等级=’老会员’ where 注册日期>=to_date(‘2004-6-7’) and 发帖数<=3000;
update user_info set 等级=’骨灰会员’ where 发帖数<=8000;
update user_info set 等级=’管理员’ where 发帖数<=10000;
update user_info set 等级=’超级管理员’ where 发帖数<=50000;
八:delete user_info where 用户ID=’AAA’;
九:select 用户ID,妮称 from user_info where 妮称 like ‘%奥运%’;
十:select count(distinct 所在地区) from user_info where发帖数>=10000;
第 三 章 连接
一、以第一章中论坛用户基本信息表的用户等级列为例,假设表中原来没有此列,现在要添加此列,但是由于论坛刚刚试行会员等级制度,因此,会员等级的显示名称有可能会变化(只是名称上有变化),比如本来是初级会员、中级会员等等,以后有可能改为士卒、将领、大将军等等。但每次变化用户等级的名称时,都需要更新表的所有行,如果表的行比较多,速度将非常慢。有什么方案解决这个问题。
二、说出在上例子中,将等级相关信息另设一个表的优点与缺点
三、接上例,会员等级的规则以发帖数为准,根据不同的发帖数量,设定会员等级,而且此会员等级的规则也有可能变化。比如本来是发100帖以内是初级用户,200帖是中级用户等等,网站试运行一段时间后,有可能改为发150帖以内是初级用户,500帖以内是中级用户,等等。修改会员等级表满足此要求。
答案:
一、再建一个用户等级表(表名user_dj),它有两列:等级编号、等级名称,等级编号中存储1级、2级、3级等等,在等级名称中,显示实际的‘初级用户’,‘中级用户’等等。
二、缺点:每次需要显示用户的等级时,都需要做两个表的连接,这需要搜索两个表。优点:等级名称的变化将会非常方便。
三、将User_dj添加两列:DJGZXX(等级规则下限),DJGZSX(等级规则上限)。
第 四 章 多行函数
一、仍以第一章中论坛用户基本信息表为例,统计当前总的用户数
二、统计上海的会员有多少名
三、统计北京最近半年内新增了多少会员
四、由大到小排序显示各地区最近一年内注册会员的总发帖数、平均发帖数,不显示总发帖数量少于十万的地区。
五、显示最近半年内注册的用户中,发帖数量超过1000的用户所在地区,以及这些地区目前各自总的会员数
答案:
一:select count(*) from user_info;
二:select count(*) from user_info where 所在地区=’上海’;
三:select count(*) from user_info where 所在地区=’北京’ and 注册日期>=’2008-3-7’;
四:select 所在地区, sum(发帖数), avg(发帖数) from user_info where 注册日期>=’2007-9-7’ group by 所在地区 having sum(发帖数)>100000;
五:select 所在地区, count(*) from user_info where 注册日期>=’2008-3-7’ and 发帖数量>=1000 group by 所在地区;
一、显示发帖数量最多的地区是哪个
二、显示有多少个地区的会员发帖数量超过10000,以及这些地区会员总的发帖数在论坛中总的帖子数量的比例。
答案:
一:select 所在地区 from user_info group by 所在地区 having sum(发帖数)=(select max(sum(发帖数)) from user_info group by 所在地区);
二:select 所在地区,sum(发帖数量), sum(发帖数量)/(select sum(发帖数量) from use_info) from user_info where 发帖数>=10000 group by 所在地区;
第 六 章 替换变量与改变输出格式
一、如果当前用户中有表T1,下面的语句可以成功执行吗:
define aa='from'
define bb='t1'
select * &aa &bb;
二、如果再定义替换变量cc:define cc='select' ,“&cc * &aa &bb;”可以执行成功吗?
三、表有NAME列,用两种方法在显示此列时,在标头中显示汉字“姓名”。
四、表有Address(地址)列,长度比较长,用命令将此列的显示宽度定为20个汉字。如果你已经将此列的显示宽度定为20个汉字了,对于列长度20个汉字的行,是否只显示前20个汉字?
五、对于DEPT(部门)列所有连续重复的行,在显示时除第一个值外,其余重复的值显示为空。
答案:
一:可以
二:不可以,因为语句的第一个单词不能是替换变量
三:方法1:select name 姓名 from 某表;
方法2:col name heading 姓名
select * from 某表;
四:col address for a20
如果长度超出,将会拐行显示
五:break on dept
第 七 章 操纵数据
一、从论坛用户基本信息表中取出用户ID、用户妮称和发帖数量三列,另外创建一个新表,新表中行数和原表中行一样多。
二、回滚段除了可以保证事务可以回滚外,还有什么作用?
三、事务如下几条语句:
A;
B;
Savepoint t1;
C;
D;
在此事务执行到语句D时,用户发出了“rollback;”命令,事务将回滚到哪个地方?
回答:
一:create n_user_info as select 用户ID,用户妮称,发帖数量 from user_info;
二:一致读
三:回滚到事务开始前的状态
第 八 章 数据类型
准备工作:
drop table tab1;
create table tab1(id number(10),name varchar2(20));
insert into tab1 values(1,'abc');
insert into tab1 values(2,'abc');
insert into tab1 values(3,'abc');
commit;
一、为tab1表添加一个地址列:address,类型为varchar2,长度50个字节。
二、将此地址列的默认值改为北京
三、表中原有三行,地址列的值为NULL,将地址列值改为北京后,原有这三个NULL值,是否会被修改为北京。
四、将姓名列的宽度改为10个字节,这个命令在姓名列不为空的情况下是否可以成功执行
五、将ID列的宽度减少为number(5),这个命令在ID列不为空的情况下是否可以成功执行
答案:
一:alter table tab1 add address varchar2(50);
二:alter table tab1 modify address default ‘北京’;
三:不会,默认值只对新插入的行有效
四:alter table tab1 modify name varchar2(10);
此命令可以成功执行,因为现在Name列的值长度最长的是3个字节。
五:alter table tab1 modify id number(5);
此命令在ID列不为空的情况下不能执行
第 九 章 约束
准备工作:
drop table tab1;
create table tab1(id number(10),name varchar2(20),addr varchar(30),);
insert into tab1(id,name) values(1,'abc');
insert into tab1(id,name) values(2,'abc');
insert into tab1(id,name) values(3,'abc');
commit;
一、表约束和列约束的区别,只有哪一种约束必须是列级的。
二、在Addr列添加非空约束,对于地址原来为空的行,将地址列改为汉字“无”。
三、以前面章节中的论坛用户基本信息表为例,它有如下列:用户ID、妮称、密码、Email、所在地区、注册日期、用户分数、发帖数,其中用户ID和Email要求不能重复,请为此两列添加合适的约束。
四、为用户基本信息表添加一个等级编号列,另创建一用户等级表,它有如下的列:等级编号、等级、发帖数量。要求等级表中有什么等级编号,用户基本信息表中才能有相应的等级编号。比如说等级表中有1,2,3,4四种等级,用户等级表也只能有这种等级的全部或部分。按照此要求,为这两个表添加合适的约束。
五、如果要求删除等级表的相应等级时,也同时删除用户基本信息表中所有此等级的行,该如何设置。
六、删除等级表,但保留用户基本信息表中的所有数据。
七、论坛要求用户ID可以重复,用户妮称也可以重复,但ID和妮称加起来不能重复,请为此要求添加合适的约束。
回答:
一:表约束是属于表,它可以包含多列。列约束属于列,它只能包含某一列。
二:update 某表 set addr=’汉字’ where addr is null;
alter table 某表 modify addr constraint 约束名 not null;
三:alter table user_info add constraint 约束名union(用户id);
alter table user_info add constraint 约束名union(email);
四:alter table user_info add 等级编号 number(5);
create table 等级表(等级编号 number(5), 等级 varchar2(50),
发帖数量 number(10) , constraint djbh primary key(等级编号) );
alter table user_info add constraint ud_djbh foreign key(等级编号) references 等级表(等级编号));
五:在User_info上添加外键时,使用on delete cascade,命令如下:
create table 等级表(等级编号 number(5), 等级 varchar2(50),
发帖数量 number(10) , constraint djbh primary key(等级编号) on delete cascade );
六:drop table 等级表 cascade constraints;
七:alter table user_info add constraint 约束名union(用户id,妮称);
第 十 章 视图
仍以论坛用户基本信息表为例,设表名为User_info,它有如下列:用户ID(不能为空)、妮称、密码、Email、所在地区、注册日期、用户分数、发帖数。
一、论坛中有一项功能,让普通用户可以按“用户ID”或“妮称”搜索其他会员的信息,但是在论坛用户基本信息表中,有一些特殊的内部管理员用户,这些用户的基本信息不希望被搜索到。而且,在用户搜索其他会员信息时,“密码”列不能被显示出来,如何解决这两点问题。
二、我按照“发帖数”列排序创建了一个视图VW1,创建语句如下:
create or replace view vw1 as select * from User_info order by 发帖数列;
我是否可以向VW1视图中插入行?是否可以进行其他的DML操作
三、由于经常需要查询不同的所在地区,我创建了如下视图:
create or replace view vw2 as select distinct 所在地区列 from User_info;
我可以在此视图中删除地区为某地的行吗?
四、我创建了一个视图VM3,创建语句如下:
create or replace view vw3 as select 妮称,所在地区,注册日期,发帖数,用户分数 from User_info;
我可以向此视图插入行吗?为什么?
五、为了使注册日期列的输出结果固定为年-月-日格式,我创建了如下视图:
create or replace view vm4 as select 用户ID,to_char(注册日期,'yyyy-mm-dd hh24:mi:ss') rq from User_info;
我们可以对此视图做什么样的DML操作?为什么?
六、如果基本表被删除了,视图会随之被删除吗?
七、如果有表TAB1,它有如下的行:
SQL> select * from tab1;
ID NAME
---------- ----------
1 ICOL$
2 I_USER1
3 CON$
4 UNDO$
5 C_COBJ#
6 I_OBJ#
7 PROXY_ROLE
8 I_IND1
9 I_CDEF2
10 I_PROXY_RO
已选择10行。
我发出如下语句:select rownum, id , name from tab1 where id>=5; 显示结果如下:
ROWNUM ID NAME
-------------------- -------- -----------------
(_______) 5 C_COBJ#
(_______) 6 I_OBJ#
(_______) 7 PROXY_ROLE
(_______) 8 I_IND1
(_______) 9 I_CDEF2
(_______) 10 I_PROXY_RO
已选择6行。
请在括号中的横线上填上ROWNUM列的显示值。
八、显示发帖数最多的十名会员的信息
思考题:
一、显示发帖数量最多的第11到20名会员信息。用两种方法完成此题,并比较哪种方法更好
二、向User_info表添加一列,“是否允许其他用户看到我的Email”,列名为find_email。以User_info表为基表创建一个视图,当此列为是时,查询此视图时,将会正常输出用户的Email。如果此列为否,查询视图时,用户Email列将显示为“该用户没有公布Email”。
答案:
一:创建一个视图,视图选择语句的条件是where 用户类型 <> ‘内部管理员’,另外,视图中不包括“密码”列。用户搜索信息时,只让他们针对此视图进行搜索,这样他们就查不出来“内部管理员”和密码列了。
二:不可以。可以更新所有行的所有列(包括排序列),也可以删除。
三:不可以。创建视图时回有Dintisct,将不能对视图进行任何DML操作
四:不可以。因为用户ID列有非空约束,而视图中不包括此列。对视图插入,将为此列添加NULL值。这将违反用户ID列的非空约束。
五:视图包含虚拟列,对视图不可以进行任何DML操作
六:不会
七:结果依次为1、2、3、4、5、6
八:select * from (select * from user_info order by 发帖数 desc) where rownum<=10;
思考题一:
col col1 noprint
select * from (select rownum col1,user_info.* from (select * from user_info order by 发帖数量 desc) where rownum<=20) where col1>=10;
还有一种方法,就是先从大到小排序取前20名,再对排序结果从小到大排序取前10名。这种方法的缺点是需要两次排序。
思考题二:
alter table user_info add find_email varchar2(2);
create or replace view vw4 as select 用户ID,妮称,所在地区,注册日期,发帖数,用户分数,case find_email when ‘是’ then email列 when ‘否’ then ‘该用户没有公布Email’ end case 用户Email from User_info;
或是用Decode实现:
create or replace view vw4 as select 用户ID,妮称,所在地区,注册日期,发帖数,用户分数,decode(find_email,‘是’,email列, ‘否’, ‘该用户没有公布Email’) 用户Email from User_info;
第 十一 章 序列、索引和同义词
一、在User_info表中添加一个num列,使用序列将此列的值定为2、4、6、8等偶数。并且最大到100,100之后重新从2开始。
二、为了提高User_info表中,按用户ID列的查找用户的速度,在用户ID列上创建索引User_info_id。
三、请问User_info_id索引中除了记录有对应表User_info中用户ID列的值外,还必须有什么信息?这项信息的作用是什么?
四、很多用户经常以妮称列为条件进行等值查寻,因为妮称中可以包含大、小写字母,当查找妮称为“abc”的行,用户希望可以将“ABC”、“Abc”、“ABc”等各种大小写字母的组合都查找出来。因此,最常见的查询妮称的条件形式如下:upper(妮称)=“ABC”,或lower(妮称)=“abc”。为了提高在妮称列中查询的速度,在妮称列上创建索引。
五、删除表会删除相应索引吗?
六、UPLOOKING用户下有一个TAB2表,其他的用户要想访问它必须UPLOOKING.TAB2,十分不方便,如何使其它用户也能直接使用TAB2访问UPLOOKING下的TAB2表。
七、有一公有同义词TAB2,它代表UPLOOKING下的TAB2表,在USER1用户下也有一TAB2表,在USER1下使用如下的语句:select * from tab2,它将访问哪个用户下的TAB2表。
答案:
一:create sequence seq1 increment by 2 maxvalue 100 cycle;
altet table user_info add num number(4);
update user_info set num=seq1;
二:create index user_info_id on user_info(用户ID);
三:索引中除了列值外,必须还有索引条目对应行的地址。
四:create index user_info_nc on user_info(upper(妮称)); 或:
create index user_info_nc on user_info(lower(妮称));
五:会
六:create public synonym tab2 for uplooking.tab2;
七:访问的是USER1下的TAB2表。当使用某一串字符访问表时,Oracle将先在当前用户的表中查找是否存在。如果当前用户中不存在,再到公有同义词中查找是否存在,如果也不存在,就会报出“对象不存在”错误。
第 十二 章 用户、权限和角色
一、创建USER2用户,密码是12345
二、将USER2用户的密码改为ABCDE
三、如何让USER2用户能够连接数据库
四、如何让USER2用户可以创建表
五、将能够连接数据库和能够在表空间中创建表的权限授于一个角色,方便以后授于新用户
六、对象权限和系统权限的区别是什么
七、因应用程序的需求,USER2用户需要能够向USER1用户中的TAB2表中插入行,为USER2分配合适的权限。
八、用户USER2将向USER1用户中TAB2表中插入行的权限又授于了UPLOOKING用户。用户USER1将USER2对TAB2插入的权限撤消了,USER2用户授于UPLOOKING的向TAB2插入的权限是否随之被撤消。
答案:
一:create user user2 identied by “12345”; --注意,密码外的双引号不可省略。如果密码是字符,才可以省略双引号
二:alter user user2 identied by ABCDE
三:为USER2授予Create session权限:grant create session to user2;
四:授予它使用表空间中空间的权限: grant unlimited tablespace to user2;
五:create role role1;
grant create session, unlimited tablespace to role1;
六:
七:grant insert on tab2 to user2;
八:会
(对象权限会级联撤消,系统权限不会级联撤消)