某数据库中包含科室表和医生表。
科室表:dept_table(deptno, dname, loc)
表中属性列依次是科室编号、科室名称、科室所在地。
科室表结构如下:
列名 | 数据据类型 | 长度 | 完整性约束 |
---|---|---|---|
deptno | char | 8 | 主键(deptno_pk) |
dname | varchar2 | 24 | 唯一(dname_uk) |
loc | varchar2 | 36 | 无 |
create table dept_table(
deptno char(8),
dname varchar(24),
loc varchar(36),
constraint deptno_pk primary key(deptno), -- 主键约束
constraint dname_uk unique(dname) -- 唯一性约束
);
医生表:doctor_table(docno, docname, age, sal, deptno)
表中属性列依次是医生编号、医生姓名、年龄、工资、所在科室编号。
医生表结构如下:
列名 | 数据类型 | 长度 | 完整性约束 |
---|---|---|---|
docno | char | 8 | 主键(docno_pk) |
docname | varchar2 | 10 | 非空 |
age | int | 无 | 年龄在18~55岁(age_ck) |
sal | number | 无 | 无 |
deptno | char | 8 | 外键(参照dept_table中的deptno)(deptno_fk) |
create table doctor_table(
docno char(8),
docname varchar(10) not null,
age int,
sal number,
deptno char(8),
constraint docno_pk primary key(docno), -- 主键约束
constraint age_ck check(age between 18 and 55), -- check约束
constraint deptno_fk foreign key(deptno) references dept_table(deptno) -- 外键约束
);
数据请自行插入,再练习下方习题
此处为补充的模拟数据,因为我很久没用Oracle了,所以是用mysql写的,可能会出问题,请读者自己甄别
-- dept_table表的数据
INSERT INTO `dept_table` VALUES ('01', '口腔科', '1楼');
INSERT INTO `dept_table` VALUES ('02', '外科', '2楼');
INSERT INTO `dept_table` VALUES ('03', '内科', '2楼');
INSERT INTO `dept_table` VALUES ('04', '耳鼻科', '2楼');
INSERT INTO `dept_table` VALUES ('05', '呼吸科', '1楼');
INSERT INTO `dept_table` VALUES ('06', '儿科', '3楼');
INSERT INTO `dept_table` VALUES ('07', '血液科', NULL);
INSERT INTO `dept_table` VALUES ('08', '神经外科', NULL);
INSERT INTO `dept_table` VALUES ('09', '皮肤科', NULL);
INSERT INTO `dept_table` VALUES ('10', '骨科', NULL);
INSERT INTO `dept_table` VALUES ('11', '妇科', NULL);
INSERT INTO `dept_table` VALUES ('12', '消化科', NULL);
-- doctor_table表的数据
INSERT INTO `doctor_table` VALUES ('01', '张三', 30, 5000, '01');
INSERT INTO `doctor_table` VALUES ('02', '李四', 30, 8000, '01');
INSERT INTO `doctor_table` VALUES ('03', '王五', 32, 900, '02');
INSERT INTO `doctor_table` VALUES ('04', '赵六', 36, 12000, '03');
INSERT INTO `doctor_table` VALUES ('05', '孙七', 29, 8000, '02');
INSERT INTO `doctor_table` VALUES ('06', '张医生', 33, 1000, '10');
INSERT INTO `doctor_table` VALUES ('07', '李医生', 33, 1900, '08');
INSERT INTO `doctor_table` VALUES ('08', '王医生', 36, 2000, '10');
INSERT INTO `doctor_table` VALUES ('09', '赵医生', 39, 18000, '10');
INSERT INTO `doctor_table` VALUES ('10', '孙医生', 29, 1000, '02');
根据各表结构,用SQL语句完成下列操作。
1)将医生表doctor_table中的docname列的数据类型修改为char(20)。
-- 修改约束 modify
alter table doctor_table modify docname char(20);
2)doctor_table表中添加一个名为chk_sal的约束,从而保证医生的工资必须大于800。
-- 添加约束 add
alter table doctor_table add constraint chk_sal check(sal > 800);
3)将张三医生的工资调高20%。
-- 更新操作 update set
update doctor_table set sal = sal*1.2 where docname = '张三';
4)删除科室号为10,工资低于2000的医生信息。
-- 删除操作 delete
delete from doctor_table where deptno=10 and sal<2000;
5)查询各个科室的科室名称及其医生人数
查询结果按照医生人数的升序排列
如果人数相同,按照科室名称降序排列。
-- asc 升序(默认)
-- desc降序
select dname, b.cnt from dept_table a, (
select deptno, count(*) as cnt
from doctor_table
group by deptno
) b
where a.deptno = b.deptno
order by b.cnt asc, dname desc;
6)查询各科室中至少有2个人工资在2500以上的科室号和医生人数。
select a.deptno, count(*)
from doctor_table a, (
select deptno
from doctor_table
where sal>2500
group by deptno
having count(*) >= 2
) b
where a.deptno = b.deptno
group by a.deptno;
7)查询平均工资超过3000的科室编号。
select deptno from doctor_table group by deptno having avg(sal)>3000;
8)查询孙七医生所在的科室名称及科室地点。
select dname, loc
from dept_table
where deptno = (
select deptno
from doctor_table
where docname='孙七'
);
9)查询姓赵的医生的姓名、年龄和所在科室名称。
-- '_'单个字符
-- '%'零个或多个
select docname, age, dname
from doctor_table a, dept_table b
where a.deptno = b.deptno and a.docname like '赵%';
10)建一个“口腔科”科室的视图dept_10,包括医生编号、医生姓名及工资。
-- 视图关键词view
create view dept_10 as
select docno, docname, sal
from doctor_table a, dept_table b
where a.deptno = b.deptno and dname='口腔科';
计算1到100的偶数和,输出
1~100的偶数和为:?
以下列出三种循环方式
PS:
- %不是取余操作
- sum是关键词
dbms_output.put_line('1~100的偶数和为:'||sum_i);
中||左右不要加空格
set serveroutput on
declare
i number := 1;
sum_i number := 0;
begin
loop
if mod(i, 2) = 0 then
sum_i := sum_i + i;
end if;
i := i+1;
exit when i > 100;
end loop;
dbms_output.put_line('1~100的偶数和为:'||sum_i);
end;
/
set serveroutput on
declare
i number := 1;
sum_i number := 0;
begin
while i <= 100 loop
if mod(i, 2) = 0 then
sum_i := sum_i + i;
end if;
i := i+1;
end loop;
dbms_output.put_line('1~100的偶数和为:'||sum_i);
end;
/
set serveroutput on
declare
sum_i number := 0;
-- for 内部声明i,不用在这里declare
begin
for i in 1..100 loop
if mod(i, 2) = 0 then
sum_i := sum_i + i;
end if;
end loop;
dbms_output.put_line('1~100的偶数和为:'||sum_i);
end;
/
用带参数的游标实现查询某部门员工的工号和姓名。
-- 游标,书P166
set serveroutput on
declare
-- 申明游标
cursor cur_emp(v_dept in varchar2) is
-- 注意用户模式
-- scott模式,书P83
select * from scott.emp
where deptno = v_dept;
v_emp scott.emp%rowtype;
begin
-- 此处以部门号为10举例
-- 打开游标
open cur_emp(10);
-- 类于高级语言的do-while循环
loop
-- 读取游标
fetch cur_emp into v_emp;
dbms_output.put_line(v_emp.empno||','||v_emp.ename);
exit when cur_emp%notfound;
end loop;
-- 关闭游标
close cur_emp;
end;
/
存储过程procedure
书P87
用存储过程实现根据给定的部门编号返回该部门的详细信息
-- in 表示输入类型参数(默认)
-- out表示输出参数类型
-- 书P190
create or replace procedure pr_dept (
v_deptno in dept_table.deptno%type,
v_dname out dept_table.dname%type,
v_loc out dept_table.loc%type
) is
begin
select dname, loc into v_dname, v_loc
from dept_table
where deptno = v_deptno;
end;
/
-- 执行操作,书P193
variable p_dname varchar2(24);
variable p_loc varchar2(36);
execute pr_dept('10', :p_dname, :p_loc);
-- 两种打印方式
print p_dname p_loc;
select :p_dname, :p_loc from dual;
创建一个存储过程,根据给定的部门,返回该部门员工的工资总和。
create or replace procedure pr_dept2 (
v_deptno in dept_table.deptno%type,
p_sum out number
) is
begin
select sum(doctor_table.sal) into p_sum
from dept_table, doctor_table
where dept_table.deptno = doctor_table.deptno
and dept_table.deptno = v_deptno;
end;
/
-- 执行操作
variable p_sum number;
execute pr_dept2('10', :p_sum);
print p_sum;
select :p_sum from dual;
函数function
书P197
创建一个函数,根据给定的部门,返回该部门员工的工资总和。
-- 函数与存储过程的主要区别是函数具有返回值
create or replace function fun_dept3 (
v_deptno in dept_table.deptno%type
) return number is
-- 申明内部变量
p_sum number;
begin
select sum(doctor_table.sal) into p_sum
from dept_table, doctor_table
where dept_table.deptno = doctor_table.deptno
and dept_table.deptno = v_deptno ;
return p_sum;
end;
/
--调用
select fun_dept3('10') from dual;
以上提及的书本为 清华大学出版社 《Oracle从入门到精通》