Oracle——操作题测试
- 一、用户和权限操作(每小题4分)
- 二、表操作(每小题4分)
- 三、查询(每小题3分)
-
-
- 1. 查找职位不是SH_CLERK和SA_MAN的雇员工种及姓名。将姓名显示为(first_name+last_name命名为”Name”)。
- 2. 查找first_name以D开头,后面仅有三个字母的雇员信息。
- 3. 查找工资高于2000的雇员信息,按部门号升序和雇员编号降序排列。
- 4. 查询有奖金的员工名和月薪、奖金,并按奖金系数排降序
- 5. 查询各个job_id的员工人数
- 6. 查询各个管理者手下员工的最低工资,其中最低工资不能低于6000,没有管理者的员工不计算在内
- 7. 查询部门地区编号为1700的员工姓名
- 8. 查询所有部门的名字,location_id,员工数量和工资平均值
- 9. 查询雇员表中工资最高的三条记录
- 10. 列出同部门中工资高于1000 的员工数量超过2 人的部门,显示部门名字、地区名称。
-
- 四、PL/SQL编程(共30分)
一、用户和权限操作(每小题4分)
1. 创建表空间myuser,数据文件为d1.dbf,表空间大小为20M
create tablespace myuser datafile 'd:\d1.dbf' size 20m;
2. 创建一个用户,用户名为rose,密码为r123,默认表空间为myuser
create user c##rose identified by r123 default tablespace myuser;
3. 为该用户授予connect角色和create table权限
grant connect,create table to c##rose;
4. 以该用户连接oracle数据库
conn c##rose/r123; (也可以界面方式截图)
二、表操作(每小题4分)
1. 使用rose用户创建表mytab,表结构如下:
作答:
该表的默认表空间为mytab
如果创建用户时没有指定默认表空间,则创建的表会自动指定users为默认表空间。
alter table mytab move tablespace myuser;
--(因为界面方式无法设置表空间,当默认的表空间为users,需要通过命令方式修改)
说明,如果通过命令的方式创建表的话,在创建完表后就将表空间加在这个表上的话,就不需要再通过上面的命令进行更改表空间了。
命令方式创建表:
create table mytab(
xh char(6) primary key,
xm varchar2(20) not null,
xb char(2) default '男' not null,
cssj date not null,
zy varchar2(50),
zxf number(3) default 0 check (zxf>=0 and zxf<=160)
)tablespace myuser;
提示:当非空约束和默认值同时存在时,要先写默认值,中间用空格隔开
2. 删除ZY字段
alter table mytab drop column zy;
3. XB字段重命名为SEX
alter table mytab rename column xb to sex;
4. 向表中插入如下记录
作答:
插入之前需用管理员身份给c##rose授权:
grant unlimited tablespace to c##rose;
5. .创建一个视图v_mytab,视图包含xh、xm、zxf三个字段,条件是1999年以后出生的记录。
--先授权:
grant create view to c##rose;
create or replace view v_mytab as select xh,xm,zxf from mytab where to_char(cssj,'yyyy')>= '1999';
6. 对ZY字段建立一个索引,名称为idx_zy,
create index idx_zxf on mytab(zxf);
三、查询(每小题3分)
进入hr模式,完成下面的查询
alter session set container=pdborcl;
alter pluggable database pdborcl open;
1. 查找职位不是SH_CLERK和SA_MAN的雇员工种及姓名。将姓名显示为(first_name+last_name命名为”Name”)。
select job_id,concat(first_name,last_name) name from employees where job_id not in('SH_CLERK','SA_MAN');
或
select job_id,first_name||last_name name from employees where job_id not in('SH_CLERK','SA_MAN');
2. 查找first_name以D开头,后面仅有三个字母的雇员信息。
select * from employees where first_name like 'D__';
3. 查找工资高于2000的雇员信息,按部门号升序和雇员编号降序排列。
select * from employees where salary>2000 order by department_id,employee_id desc;
4. 查询有奖金的员工名和月薪、奖金,并按奖金系数排降序
select first_name,salary,salary*commission_pct comm from employees where commission_pct is not null order by commission_pct desc;
注意:有奖金的意思就是奖金 is not null
5. 查询各个job_id的员工人数
select job_id,count(employee_id) renshu from employees group by job_id;
6. 查询各个管理者手下员工的最低工资,其中最低工资不能低于6000,没有管理者的员工不计算在内
select manager_id,min(salary) from employees where manager_id is not null group by manager_id having min(salary)>=6000;
7. 查询部门地区编号为1700的员工姓名
select location_id,first_name from employees e join departments d on e.department_id=d.department_id where location_id=1700;
8. 查询所有部门的名字,location_id,员工数量和工资平均值
select department_name,location_id,count(employee_id),round(avg(salary),2) from employees e join departments d on e.department_id=d.department_id group by department_name,location_id;
9. 查询雇员表中工资最高的三条记录
select rownum,e.* from (select * from employees order by salary desc) e where rownum<=3;
10. 列出同部门中工资高于1000 的员工数量超过2 人的部门,显示部门名字、地区名称。
select department_name,city,count(*) from employees e,departments d,locations l
where e.department_id=d.department_id and d.location_id=l.location_id
and salary>7000 group by department_name,city having count(*)>2;
或
select d.department_name,l.street_address from departments d,locations l
where l.location_id = d.location_id and d.department_id in (
select department_id from employees
where salary>1000 group by department_id having count(employee_id)>2);
或
select department_name,city,total from
(select department_id,count(*) from employees where salary>7000 group by department_id) e,
departments d,locations l where e.deoartment_id=d.department_id and d.location_id=l.location_id and total>2;
四、PL/SQL编程(共30分)
以下题目,均针对scott用户
1. 编写一个块,根据员工号,获得员工到目前为止参加工作年限(保留到整数),员工号不存在时提示“此员工号不存在”。(8分)
方案一:
declare
eno emp.empno%type:=&no;
vyear number;
begin
select extract(year from sysdate)-extract(year from hiredate) into vyear from emp where empno=eno;
exception
when no_data_found then
dbms_output.put_line('此员工号不存在');
end;
方案二:
declare
vno emp.empno%type:=&no;
years number(2);
begin
select round(months_between(sysdate,hiredate)/12) into years from emp where empno=vno;
dbms_output.put_line(years);
exception
when no_data_found then
dbms_output.put_line('此员工号不存在');
end;
2. 写一个存储过程addDept,实现添加一个部门功能,部门编号为当前最大部门编号加1,其它信息通过in模式参数传入。调用此过程(10分)
方案一:
create or replace procedure mydure(vdname dept.dname%type,vloc dept.loc%type)
is
vdno dept.deptno%type;
begin
select max(deptno)+1 into vdno from dept;
insert into dept values(vdno,vdname,vloc);
end;
declare
vdname dept.dname%type := '&name';
vloc dept.loc%type := '&loc';
begin
mydure(vdname,vloc);
end;
select * from dept;
方案二:
create or replace procedure addept(pname dept.dname%type,ploc dept.loc%type)
is
pno dept.deptno%type;
begin
select max(deptno)+1 into pno from dept;
insert into dept values(pno,pname,ploc);
if sql%rowcount<>0 then
commit;
dbms_output.put_line('插入成功');
else
dbms_output.put_line('插入失败');
end if;
end;
--过程调用
begin
addDept('快乐部','北京');
end;
3. 编写一个函数,计算员工应交个人所得税,1000元以下的员工,不交税,1000-2000元的按照5%缴纳,2000以上的10%缴纳。依据此函数,编写调用模块,可以输出所有员工应交税额(12分)
create or replace function paytax(fno emp.empno%type) return number
is
fsal emp.sal%type;
ftax number;
begin
select sal into fsal from emp where empno=fno;
if fsal<=1000 then
ftax:=0;
elsif fsal<=2000 then
ftax:=fsal*0.05;
else
ftax:=fsal*0.1;
end if;
return ftax;
end;
--函数调用
declare
cursor cur_no is select empno from emp;
tax number;
cno number;
begin
open cur_no;
loop
fetch cur_no into cno;
exit when cur_no%notfound;
tax:=paytax(cno);
dbms_output.put_line(cno||' '||tax);
end loop;
close cur_no;
end;