数据库SQL基本操作
1、查询表结构
desc 表名
2、显示当前连接用户
show user
3、查看系统拥有哪些用户
select * from all_users;
4、查询当前用户下所有对象
select * from tab;
5、回滚事务
roll;
rollback;
6、提交事务
commit;
1. 创建教材的学生-课程数据库中的三个表.定义表时请注意数据类型问题,Oracle的数据类型请参照本实验讲义.要求学号在20000000至99999999之间,年龄<29,性别只能是’男’或’女’,姓名非空。
create table student( sno number(12) constraint pk_student primary key constraint ck_sno check(sno>=20000000 and sno<=99999999), sname char(20) not null constraint u_sname unique, sage number(3) constraint ck_sage check(sage<29), ssex char(2) constraint ck_ssex check(ssex='男' or ssex='女'), sdept char(10) ); create table course( cno number(4) constraint pk_course primary key, cname char(20), cpno number(4) constraint fk_cpno references course (cno), ccredit number(4) ); create table sc( sno number(12) constraint ck_sno check(sno>=20000000 and sno<=99999999), cno number(4), grade number(3), constraint pk_sc primary key(sno,cno), constraint fk_sc foreign key(cno) references course(cno) );
2. 修改学生-课程数据库的3个表的定义,分别为每个表建立主码和外码(如果有),并输入数据,验证实体完整性和参照完整性。
insert into student values(20140000,'哈哈',20,'男','软件工程'); insert into student values(20140001,' hehe',20,'男','软件工程') insert into student values(20140002,' nike',19,'男','软件工程') insert into course values(10,'数据库',null,2); insert into course values(11,'数据库2',null,2); insert into course values(12,'数据库3',null,2); insert into course values(13,'c++',10,2); insert into course values(14,'java',12,3); insert into sc values(20140000,10,99); insert into sc values(20140001,11,98); insert into sc values(20140002,10,99); insert into sc values(20140003,11,98);
3. 建立部门表DEPT,要求部门名称Dname列取值唯一,部门编号Deptno列为主码;建立职工表EMP,要求每个职工的应发工资不得超过3000元。应发工资实际上就是实发工资列Sal与扣除项Deduct之和。
create table dept( dname char(10) constraint u_dname unique, deptno number(12) constraint pk_dept primary key ) create table emp( wage number(5) constraint ck_wage check(wage<=3000), sal number(5), deduct number(5) --constraint ck_deduct check(deduct=wage-sal)
) 4. 对以上建立的表建立索引。 create unique index idx_student on student(sname); create unique index idx_course on course(cname); create unique index idx_sc on sc(sno); create unique index idx_dept on dept(deptno); create unique index idx_emp on emp(wage);
/*重建表*/
drop table sc cascade constraint;
drop table student cascade constraint;
drop table course cascade constraint; Create table Student
(Sno number(8) Constraint ck_sno check (Sno>20000000 and sno<99999999) ,
Sname varchar2(8) not null,
Ssex char(2),
Sage number(2) Constraint ck_sage check (sage<29) ,
Sdept varchar2(20),
Constraint ck_ss check (Ssex in ('男','女')),
constraint PK_student primary key (sno)); Create table Course
(Cno number(4) constraint pk_course primary key,
Cname varchar2(20),
Cpno number(2),
Ccredit number(2)); Create table SC
(Sno number(8),
Cno number(4),
Grade number(3),
Constraint pk_SC Primary key (Sno,Cno),
Constraint fk_s Foreign key (sno ) references student(Sno),
Constraint fk_c Foreign key (cno ) references course(Cno)
); Insert Into Student(Sno,Sname,Ssex,Sage,Sdept)
Values(20070001,'李佳','女',20,'MA');
Insert Into Student(Sno,Sname,Ssex,Sage,Sdept)
Values(20070002,'刘明','男',19,'IS');
Insert Into Student(Sno,Sname,Ssex,Sage,Sdept)
Values(20070003,'王添','男',18,'MA');
Insert Into Student(Sno,Sname,Ssex,Sage,Sdept)
Values(20070004,'张力','女',21,'IS');
Insert Into Student(Sno,Sname,Ssex,Sage,Sdept)
Values(20070005,'张力','女',19,'CS');
Insert Into Student(Sno,Sname,Ssex,Sage,Sdept)
Values(20070006,'张力','男',19,'MA'); Insert Into Course(Cno,Cname,Cpno,Ccredit)
Values(1,'数据库原理',5,2);
Insert Into Course(Cno,Cname, Ccredit)
Values(2,'数学',2);
Insert Into Course(Cno,Cname,Cpno, Ccredit)
Values(3,'信息系统',1,4);
Insert Into Course(Cno,Cname,Cpno, Ccredit)
Values(4,'操作系统',6,3);
Insert Into Course(Cno,Cname,Cpno,Ccredit)
Values(5,'数据结构',7,4);
Insert Into Course(Cno,Cname,Ccredit)
Values(6,'数据处理',2);
Insert Into Course(Cno,Cname,Cpno,Ccredit)
Values(7,'PASCAL语言',6,4); Insert Into SC(Sno,Cno, Grade) Values(20070001,1,92);
Insert Into SC(Sno,Cno, Grade) Values(20070001,2,85);
Insert Into SC(Sno,Cno, Grade) Values(20070001,3,88);
Insert Into SC(Sno,Cno, Grade) Values(20070002,2,90);
Insert Into SC(Sno,Cno, Grade) Values(20070002,3,80); Insert Into SC(Sno,Cno, Grade) Values(20070001,4,92);
Insert Into SC(Sno,Cno, Grade) Values(20070001,5,85);
Insert Into SC(Sno,Cno, Grade) Values(20070001,6,88);
Insert Into SC(Sno,Cno, Grade) Values(20070003,2,90);
Insert Into SC(Sno,Cno, Grade) Values(20070003,3,80); Insert Into SC(Sno,Cno, Grade) Values(20070001,7,92);
Insert Into SC(Sno,Cno, Grade) Values(20070005,4,92);
Insert Into SC(Sno,Cno, Grade) Values(20070003,1,85);
Insert Into SC(Sno,Cno, Grade) Values(20070003,4,88);
Insert Into SC(Sno,Cno, Grade) Values(20070002,1,90);
Insert Into SC(Sno,Cno, Grade) Values(20070002,5,80); 二、数据查询,对实验一建立的学生-课程数据库中的表进行查询
1、查询学生的基本信息;
select * from student;
2、查询“CS”系学生的基本信息;
select * from student where sdept='CS';
3、查询“CS”系学生年龄不在19到21之间的学生的学号、姓名;
select sno,sname from student
where sdept='CS' and ( sage <19 or sage >21 );
4、找出最大年龄;
select max(sage) from student;
5、找出“CS”系年龄最大的学生,显示其学号、姓名;
select sno , sname from student
where sdept='CS' and sage=
(select max(sage) from student where sdept='CS')
6、找出各系年龄最大的学生的年龄;
select sdept, max(sage) from student
Group by sdept
7、统计“CS”系学生的人数;
select count(*) from student
where sdept='CS' 8、统计各系学生的人数,结果按升序排列;
select sdept,count(*)
from student
group by sdept
order by count(*) asc
9、按系统计各系学生的平均年龄,结果按降序排列;
select sdept,avg(sage)
from student
group by sdept
order by avg(sage) desc
10、查询每门课程的课程名;
select cname from course
11、查询无先修课的课程的课程名和学时数;
select cname,ccredit from course
where cpno is null
12、统计无先修课的课程的学时总数;
select count(*) from course
where cpno is null
13、统计每位学生选修课程的门数、学分及其平均成绩; 统计选修每门课程的学生人数及各门课程的平均成绩;
select sno,count(sc.cno),sum(ccredit),avg(grade) from sc,course
where course.cno=sc.cno
group by sno;
select course.cno,count(sno),avg(grade) from course,sc
where course.cno=sc.cno
group by course.cno;
14、找出平均成绩在85分以上的学生,结果按系分组,并按平均成绩的升序排列; -
select sc.sno,sdept,avg(grade) from sc,student
where sc.sno=student.sno and (select avg(grade) from sc)>85
group by sc.sno,sdept
order by avg(grade) asc
15、查询选修了“1”或“2”号课程的学生学号和姓名;
select student.sno,student.sname from student,sc
where student.sno=sc.sno and (1 in cno or 2 in cno)
group by student.sno,student.sname
16、查询选修了课程名为“数据库系统”且成绩在60分以下的学生的学号、姓名和成绩;
select student.sno,student.sname,grade from student,course,sc
where course.cname='数据库原理' and grade<60 and student.sno=sc.sno
and course.cno=sc.cno
17、查询每位学生选修了课程的学生信息(显示:学号,姓名,课程号,课程名,成绩); select student.sno,student.sname,course.cno,cname,grade
from student,course,sc
where student.sno=sc.sno and course.cno=sc.cno
group by student.sno,student.sname,course.cno,cname,grade
18、查询没有选修课程的学生的基本信息; -
select student.sno,sname,ssex,sage,sdept from student,sc
where cno is null and student.sno=sc.sno
group by student.sno,sname,ssex,sage,sdept
19、查询选修课程成绩至少有一门在80分以上的学生学号;
select sno from sc
where grade>80
group by sno
20、查询选修了3门以上课程的学生学号;
select sno from sc s1
where (select count(cno) from sc s2 where s1.sno=s2.sno group by sno)>3
group by sno
21、查询选修课程成绩均在80分以上的学生学号;
select sno from sc s1
where 80<all (select grade from sc s2 where s1.sno=s2.sno group by sno,grade)
group by sno
三、 视图操作:
1、 定义“IS”系学生基本情况视图V_IS 并查询结果;
create view V_IS
as
select SNO,SNAME,SSEX,SAGE,SDEPT from student
where sdept='IS';
select * from V_IS;
2、 将S,C,SC表中学生的学号,姓名,课程号,课程名,成绩定义为视图V_S_C_G并查询结果;
create view V_S_C_G
as
select s.sno,s.sname,c.cno,c.cname,grade from student s,course c,sc;
select * from V_S_C_G;
3、 将各系学生人数,平均年龄定义为视图V_NUM_AVG并查询结果;
create view V_NUM_AVG(sdept,count,avg)
as
select sdept,count(sno),avg(sage) from student
group by sdept;
select * from V_NUM_AVG;
4、 定义一个反映学生出生年份的视图V_YEAR并查询结果;
create view V_YEAR(name,birth)
as
select sname,2016-sage from student
select * from V_YEAR; 5、 将各位学生选修课程的门数及平均成绩定义为视图V_AVG_S_G并查询结果;
create view V_AVG_S_G(sno,cno_count,grade_avg)
as
select sno,count(cno),avg(grade) from sc
group by sno
select * from V_AVG_S_G
6、 将各门课程的选修人数及平均成绩定义为视图V_AVG_C_G并查询结果;
create view V_AVG_C_G(cno,count,avg)
as
select cno,count(sno),avg(grade) from sc
group by cno
select * from V_AVG_C_G 7、 建立视图V_AVG_A查询平均成绩为90分以上的学生学号、姓名和成绩;
create view V_AVG_A(sno,sname,grade_avg)
as
select student.sno,sname,avg(grade) from student,sc
where student.sno=sc.sno
group by sno
having avg(grade)>90 8、 建立视图V_AVG_B查询各课成绩均大于平均成绩的学生学号、姓名、课程和成绩;
create view V_AVG_B
as
select student.sno,sname,s1.cno,s1.grade from student,sc s1,sc s0
where student.sno=s1.sno and s0.grade>all(select avg(grade) from sc s2 where s2.cno=s1.cno
group by cno)
group by student.sno,sname,s1.cno,s1.grade;
/*SELECT Sno,Sname,Cname,Grade FROM V_S_C_G vscg
WHERE NOT EXISTS
(SELECT Sno,Sname,V_S_C_G.Cno,Cname,Grade,avg_grade
FROM V_S_C_G,V_AVG_C_G
WHERE V_S_C_G.Cno = V_AVG_C_G.Cno AND Grade < avg_grade AND vscg.Sno = V_S_C_G.Sno);*/ 9、 建立视图V_AVG_C按系统计各系平均成绩在80分以上的人数,结果按降序排列;
create view V_AVG_C(sc_sno,sdept,avg)
as
select sc.sno,sdept,avg(grade) from sc,student
where sc.sno=student.sno and (select avg(grade) from sc)>80
group by sc.sno,sdept
order by avg(grade) desc
10、 通过视图V_IS,分别将学号为“S1”和“S4”的学生姓名更改为“S1_MMM”,”S4_MMM” 并查询结果;
create view V_IS
as
select * from student;
update V_IS
set sname='S1_MMM' where sno=20070001;
update V_IS
set sname='S4_MMM' where sno=20070004; 11、 通过视图V_IS,新增加一个学生记录 (‘S12’,’YAN XI’,19,’IS’),并查询结果; insert into V_IS(sno,sname,sage,sdept)
values(20421412,'YAN XI',19,'IS')
select * from V_IS
12、 通过视图V_IS,新增加一个学生记录 ('S13','YAN XI',19,'MA'),并查询结果;
insert into V_IS(sno,sname,sage,sdept)
values(20421413,'YAN XI',19,'MA')
select * from V_IS
13、 通过视图V_IS,删除学号为“S12”和“S3”的学生信息,并查询结果;
delete from V_IS
where sno=20421412 or sno=20070003
select * from V_IS
1 利用 LOOP 循环方式计算 1+3+5+7+9。代码如下:
SET SERVEROUTPUT ON
DECLARE
i NUMBER;
sum1 NUMBER;
BEGIN
i:=1;
sum1:=0;
LOOP
IF mod(i,2)!=0 THEN
sum1:=sum1+i;
END IF;
i:=i+1;
IF(i>9) THEN
EXIT;
END IF;
END LOOP;
DBMS_OUTPUT.PUT_LINE(sum1);
END; SET SERVEROUTPUT ON
DECLARE
E_name emp.ename%type;
E_no emp.empno%type;
E_sal emp.sal%type;
E_deptno emp.deptno%type;
E_hiredate emp.hiredate%type;
BEGIN
select empno,ename,hiredate,sal,deptno INTO E_no,E_name,E_hiredate,E_sal , E_deptno FROM emp WHERE empno='';
DBMS_OUTPUT.PUT_LINE(E_no||'姓名是:'||E_name ||'入职日期:'||E_hiredate ||'工资为:'||E_sal || E_deptno);
end; 3.检索工资大于700的员工工资并输出,同时对可能发生的异常进行处理。
declare
v_sal emp.sal%type;
begin
select sal into v_sal from emp where sal>=700;
exception
when no_data_found then
dbms_output.put_line('no data!');
when too_many_rows then
dbms_output.put_line('too many row');
when others then
null;
end; 4.编写PL/SQL程序块,完成如下功能:输入一个员工号,修改该员工的工资,如果该员工为10号部门,工资增加100;若为20号部门,工资增加160;若为30号部门,工资增加200;否则增加300。用if 和case 结构实现。
/*if*/
set serveroutput on
declare
v_eno emp.empno%TYPE:=&empno;
v_esal emp.sal%TYPE;
v_edept emp.deptno%TYPE;
begin
select deptno into v_edept from emp where v_eno=empno;
if v_edept=10
then update emp set sal=sal+100 where v_eno=empno;
elsif v_edept=20
then update emp set sal=sal+160 where v_eno=empno;
elsif v_edept=30
then update emp set sal=sal+200 where v_eno=empno;
else
update emp set sal=sal+300 where v_eno=empno;
end if;
end;
/*case*/
set serveroutput on
declare
v_eno emp.empno%TYPE:=&empno;
v_esal emp.sal%TYPE;
v_edept emp.deptno%TYPE;
begin
select deptno into v_edept from emp where v_eno=empno;
case
when v_edept=10
then update emp set sal=sal+100 where v_eno=empno;
when v_edept=20
then update emp set sal=sal+160 where v_eno=empno;
when v_edept=30
then update emp set sal=sal+200 where v_eno=empno;
else
update emp set sal=sal+300 where v_eno=empno;
end case;
end; 5.用3种循环语句来实现将1到50,50个数输入到某个表中。
create table num(
num number(10)
);
/*case1*/
set SERVEROUTPUT ON;
declare
v_num num.num%TYPE;
begin
v_num:=0;
loop
v_num:=v_num+1;
insert into num values(v_num);
exit when v_num=50;
end loop;
end; /*case2*/
set SERVEROUTPUT ON;
declare
v_num num.num%TYPE;
begin
v_num:=0;
while v_num<50 loop
v_num:=v_num+1;
insert into num values(v_num);
end loop;
end; /*case3*/
set SERVEROUTPUT ON;
declare
v_num num.num%TYPE;
begin
for v_num in 0..50 loop
insert into num values(v_num);
end loop;
end; 6.系统的自定义异常
查询某个部门的平均工资,如果此工资没有在2000~3000之间,触发自定义异常,请编写PL/SQL来处理此异常。并输出“此部门的平均工资不在2k到3k之间”。 如果你能给此自定义异常分配一个异常号,及异常名(昵称),那自然是极好的。如果不能,也没关系。
set SERVEROUTPUT ON
declare
v_avg emp.sal%TYPE;
e_salout exception;
begin
select avg(sal) into v_avg from emp;
if v_avg < 2000 or v_avg > 3000
then raise e_salout;
end if;
exception
when e_salout
then dbms_output.put_line('此部门的平均工资不在2k到3k之间');
end;
1.操作职工号为7788的职工信息,如果存在该职工,修改他的工资,如果没有匹配则插入一新行。(隐式游标的应用).
set serveroutput on
begin
update emp set sal=sal+100 where emp.empno=7788;
if sql%notfound then
insert into emp(empno,ename,job,mgr,sal,comm,deptno) values(7778,"strstr","analyst",7566,3640,0,20);
end if;
end; 2. 游标变量的应用,阅读并执行下列代码,体会游标变量的应用。
PL/SQL中,可以声明游标变量,在运行时刻设置游标对应的查询语句,可以动态实现查询。游标变量的使用步骤如下:
1)声明游标变量:TYPE type_name IS REF CURSOR RETURN return_type;
2)打开游标变量: 如果要将一个游标变量与一个特定的select 语句关联,则需 Open 将其打开,语法如下:OPEN cursor_variable FOR select_statements;
3)循环处理游标的内容。
4)关闭游标变量: CLOSE cursor_variable;
游标变量的应用:使用同一游标打开多个查询
create or replace procedure print_emp as
type rc is ref cursor;
v_rc rc;
v_emp emp%rowtype;
v_ename varchar2(40);
v_dname varchar2(40);
v_loc varchar2(40);
begin
open v_rc for select * from emp order by job;
dbms_output.put_line(' 雇员信息 ' );
dbms_output.put_line(' ======================');
dbms_output.put_line(' 序号 姓名 职务 薪水');
loop
fetch v_rc into v_emp;
exit when v_rc%NOTFOUND;
dbms_output.put_line(rpad(to_char(v_rc%ROWCOUNT),8,' ')||rpad(V_emp.ename,10,' ')|| rpad(V_emp.job,10,' ')|| rpad(V_emp.sal,10,' '));
end loop; open v_rc for select ename,dname,loc from emp,dept
where emp.deptno=dept.deptno order by dname;
dbms_output.put_line(' 工作信息 ' );
dbms_output.put_line(' =======================');
dbms_output.put_line(' 序号 姓名 部门 地点');
loop
fetch v_rc into v_ename,v_dname,v_loc;
exit when v_rc%NOTFOUND;
dbms_output.put_line(rpad(to_char(v_rc%ROWCOUNT),8,' ')||rpad(V_ename,12,' ')|| rpad(V_dname,12,' ')|| rpad(V_loc,10,' '));
end loop;
close v_rc;
end print_emp;
3.游标参数的应用。并执行下列代码,输入不同的参数值,体会游标参数的应用。
游标的SELECT语句没有WHERE子句,或者用WHERE子句指定了一个固定的条件,这样每次都查询同样的数据。在更多的情况下,可能要根据实际情况查询不同的数据。为了通过游标对数据进行更加灵活的处理,可以为游标定义参数,这些参数可以用在WHERE子句中。在打开游标时,指定实际的参数值,这样游标在每次打开时,可以根据不同的实际参数值,返回所需的不同数据。
定义带参数的游标的语法格式为:
DECLARE CURSOR 游标名(参数1, 参数2, ...) IS SELECT语句;
其中参数的定义方法与子程序中的参数定义完全相同,可以指定默认值。在用OPEN命令打开游标时,要向游标提供实际参数,游标根据提供的参数值,查询符合条件的数据。打开游标的语法格式为:
OPEN游标名(实际参数1, 实际参数2...)
阅读下面的查询
例子:
DECLARE
CURSOR cur_6(d_no IN emp.deptno%type, min_sal IN emp.sal%type := 1000) IS SELECT ename, sal, hiredate FROM emp WHERE deptno = d_no and sal >= min_sal;
e cur_6%rowtype;
BEGIN
if not cur_6%ISOPEN then
--如果游标没有打开,则打开它
open cur_6(20, 2000);
END if;
fetch cur_6
INTO e; --取出第一行数据
while cur_6%found loop
dbms_output.put_line('姓名:' || e.ename || '工资:' || e.sal ||
' 工作时间:' || e.hiredate);
fetch cur_6
INTO e;
END loop;
dbms_output.put_line('员工总数:' || cur_6%rowcount); --获取的总行数
close cur_6; --关闭游标
END;
4. 编写程序利用3种循环统计并输出各个部门的平均工资。 --case1
set serveroutput on
declare
v_sal emp.sal%type;
v_deptno emp.deptno%type;
v_cnt10 number;v_cnt20 number;v_cnt30 number;
v_sum10 number;v_sum20 number;v_sum30 number;
v_avg10 number;v_avg20 number;v_avg30 number;
cursor c_emp is select sal,deptno from emp; begin
if (not c_emp%isopen)then
open c_emp;
end if; v_sum10:=0;v_sum20:=0;v_sum30:=0;
v_cnt10:=0;v_cnt20:=0;v_cnt30:=0;
loop
fetch c_emp into v_sal,v_deptno;
exit when c_emp%notfound;
if v_deptno = 10 then
v_cnt10:=v_cnt10+1;
v_sum10:=v_sum10+v_sal;
end if;
if v_deptno = 20 then
v_cnt20:=v_cnt20+1;
v_sum20:=v_sum20+v_sal;
end if;
if v_deptno = 30 then
v_cnt30:=v_cnt30+1;
v_sum30:=v_sum30+v_sal;
end if;
end loop; v_avg10:=v_sum10/v_cnt10;
v_avg20:=v_sum20/v_cnt20;
v_avg30:=v_sum30/v_cnt30; dbms_output.put_line('deptno '||'avg_sal');
dbms_output.put_line('10 '||v_avg10);
dbms_output.put_line('20 '||v_avg20);
dbms_output.put_line('30 '||v_avg30);
end; --case2
set serveroutput on
declare
v_sal emp.sal%type;
v_deptno emp.deptno%type;
v_cnt10 number;v_cnt20 number;v_cnt30 number;
v_sum10 number;v_sum20 number;v_sum30 number;
v_avg10 number;v_avg20 number;v_avg30 number;
cursor c_emp is select sal,deptno from emp; begin
if (not c_emp%isopen)then
open c_emp;
end if; v_sum10:=0;v_sum20:=0;v_sum30:=0;
v_cnt10:=0;v_cnt20:=0;v_cnt30:=0;
fetch c_emp into v_sal,v_deptno;
while c_emp%found loop
if v_deptno = 10 then
v_cnt10:=v_cnt10+1;
v_sum10:=v_sum10+v_sal;
end if;
if v_deptno = 20 then
v_cnt20:=v_cnt20+1;
v_sum20:=v_sum20+v_sal;
end if;
if v_deptno = 30 then
v_cnt30:=v_cnt30+1;
v_sum30:=v_sum30+v_sal;
end if;
fetch c_emp into v_sal,v_deptno;
end loop; v_avg10:=v_sum10/v_cnt10;
v_avg20:=v_sum20/v_cnt20;
v_avg30:=v_sum30/v_cnt30; dbms_output.put_line('deptno '||'avg_sal');
dbms_output.put_line('10 '||v_avg10);
dbms_output.put_line('20 '||v_avg20);
dbms_output.put_line('30 '||v_avg30);
end; --case3
set serveroutput on
declare
v_sal emp.sal%type;
v_deptno emp.deptno%type;
v_cnt10 number;v_cnt20 number;v_cnt30 number;
v_sum10 number;v_sum20 number;v_sum30 number;
v_avg10 number;v_avg20 number;v_avg30 number;
cursor c_emp is select sal,deptno from emp; begin
v_sum10:=0;v_sum20:=0;v_sum30:=0;
v_cnt10:=0;v_cnt20:=0;v_cnt30:=0;
for v_row in c_emp loop
if v_row.deptno = 10 then
v_cnt10:=v_cnt10+1;
v_sum10:=v_sum10+v_row.sal;
end if;
if v_row.deptno = 20 then
v_cnt20:=v_cnt20+1;
v_sum20:=v_sum20+v_row.sal;
end if;
if v_row.deptno = 30 then
v_cnt30:=v_cnt30+1;
v_sum30:=v_sum30+v_row.sal;
end if;
end loop; v_avg10:=v_sum10/v_cnt10;
v_avg20:=v_sum20/v_cnt20;
v_avg30:=v_sum30/v_cnt30; dbms_output.put_line('deptno '||'avg_sal');
dbms_output.put_line('10 '||v_avg10);
dbms_output.put_line('20 '||v_avg20);
dbms_output.put_line('30 '||v_avg30);
end;
1.编写过程,打印全体雇员信息PrintEmpRecord。
set serveroutput on;
create or replace procedure PrintEmpRecord as
v_emp emp%rowtype;
cursor cs is select * from emp;
begin
if not cs%isopen then
open cs;
end if;
fetch cs into v_emp;
while cs%found loop
dbms_output.put_line(rpad(to_char(cs%rowcount),8,' ')||rpad(v_emp.ename,10,' ')||rpad(to_char(v_emp.empno),10,' ')||rpad(v_emp.job,10,' ')||rpad(to_char(v_emp.sal),10,' ')||rpad(to_char(v_emp.hiredate),16,' '));
fetch cs into v_emp;
end loop;
close cs;
end PrintEmpRecord;
exec PrintEmpRecord; 2.把雇员编号empno作为参数,设计过程SearchEmp查询并打印该雇员信息。
set serveroutput on;
create or replace procedure SearchEmp(p_empno in emp.empno%type) as
v_emp emp%rowtype;
begin
select * into v_emp from emp where empno = p_empno;
dbms_output.put_line(rpad(v_emp.ename,10,' ')||rpad(to_char(v_emp.empno),10,' ')||rpad(v_emp.job,10,' ')||rpad(to_char(v_emp.sal),10,' ')||rpad(to_char(v_emp.hiredate),16,' '));
exception
when no_data_found then
dbms_output.put_line('no_data_found');
end SearchEmp; 3. 创建一个存储过程,以部门号为参数,查询该部门的平均工资,并输出该部门中比平均工资高的员工号、员工名。
create or replace procedure dept_mt_avg(p_deptno in emp.deptno%type) as
cursor cs is select ename,empno from emp where deptno = p_deptno and sal>(select avg(sal) from emp where deptno = p_deptno group by deptno);
begin
for v_emp in cs loop
dbms_output.put_line(v_emp.ename||' '||v_emp.empno);
end loop;
end dept_mt_avg;
exec dept_mt_avg(10); 4. 创建一个存储过程,以部门号为参数,返回该部门的人数和最高工资。
create or replace procedure dept_maxSal_count(p_deptno in emp.deptno%type) as
cursor cs is select count(*) count,max(sal) max_sal from emp where deptno = p_deptno;
begin
for v_emp in cs loop
dbms_output.put_line(v_emp.count||' '||v_emp.max_sal);
end loop;
end dept_maxSal_count;
exec dept_maxSal_count(10); 5.创建一个以部门号为参数,返回该部门最高工资的函数。
create or replace function dept_maxSal(p_deptno in emp.deptno%type) return number as
v_sal emp.sal%type;
begin
select max(sal) into v_sal from emp where deptno = p_deptno;
return v_sal;
end; select dept_maxSal(10) from dual; 6.设计一个函数,实现按雇员编号empno得到雇员的新的工资额。新的工资的计算方法为参加工作5年以下的,工资上涨5%;参加工作6-10年的,工资上涨8%;参加工作11-15年的,工资上涨10%;参加工作16-20年的,工资上涨15%;参加工作20年以上的,工资上涨20%; CREATE OR REPLACE FUNCTION NewSal( v_empno emp.deptno%TYPE )
RETURN emp.sal%TYPE
AS
v_newsal emp.sal%TYPE := 0;
v_sysdate DATE;
v_hiredate emp.hiredate%TYPE;
v_workdate NUMBER; BEGIN
SELECT hiredate INTO v_hiredate FROM emp
WHERE empno = v_empno;
SELECT SYSDATE() INTO v_sysdate FROM DUAL;
SELECT v_sysdate - v_hiredate INTO v_workdate FROM DUAL; SELECT sal INTO v_newsal FROM emp WHERE empno = v_empno; IF v_workdate < 365*5 THEN
v_newsal := v_newsal * 1.05;
ELSIF v_workdate BETWEEN 365*6 AND 365*10 THEN
v_newsal := v_newsal * 1.08;
ELSIF v_workdate BETWEEN 365*11 AND 365*15 THEN
v_newsal := v_newsal * 1.1;
ELSIF v_workdate BETWEEN 365*16 AND 365*20 THEN
v_newsal := v_newsal * 1.15;
ELSE
v_newsal := v_newsal * 1.20;
END IF;
RETURN v_newsal; END; DECLARE
BEGIN
dbms_output.put_line( Newsal( &empno ) );
END;
(1) 为emp表创建一个触发器,当执行插入操作时,统计操作后员工人数;当执行更新工资操作时,统计更新后员工平均工资;当执行删除操作时,统计删除后各个部门的人数
CREATE OR REPLACE TRIGGER trg_emp_dml
AFTER INSERT OR UPDATE OR DELETE ON emp
DECLARE
v_count NUMBER;
v_sal NUMBER(6,2);
BEGIN
IF INSERTING THEN
SELECT count(*) INTO v_count FROM emp;
DBMS_OUTPUT.PUT_LINE(v_count);
ELSIF UPDATING THEN
SELECT avg(sal) INTO v_sal FROM emp;
DBMS_OUTPUT.PUT_LINE(v_sal);
ELSE
FOR v_dept IN (SELECT deptno,count(*) num FROM emp
GROUP BY deptno) LOOP
DBMS_OUTPUT.PUT_LINE(v_dept.deptno||' '||v_dept.num);
END LOOP;
END IF;
END trg_emp_dml; (2) 为emp表创建一个触发器,修改员工工资时,保证修改后的工资高于修改前的工资。
CREATE OR REPLACE TRIGGER trg_emp_update_row
BEFORE UPDATE OF sal ON emp
FOR EACH ROW
WHEN(new.sal<=old.sal)
BEGIN
RAISE_APPLICATION_ERROR
(-20001,'The salary is lower!');
END trg_emp_update_row; (3) 创建一个包括员工及其所在部门信息的视图empdept,然后向视图中插入一条记录(2345,’TOM’,3000,’SALES’)。
CREATE OR REPLACE VIEW empdept
AS
SELECT empno,ename,sal,dname
FROM emp,dept WHERE emp.deptno=dept.deptno
WITH CHECK OPTION;
INSERT INTO empdept
VALUES(2345, 'TOM',3000, 'SALES');
*
ERROR 位于第 1 行:
ORA-01733: 此处不允许虚拟列
CREATE OR REPLACE TRIGGER trig_view
INSTEAD OF INSERT ON empdept
FOR EACH ROW
DECLARE
v_deptno dept.deptno%type;
BEGIN
SELECT deptno INTO v_deptno
FROM dept WHERE dname=:new.dname;
INSERT INTO emp(empno,ename,sal,deptno)
VALUES(:new.empno,:new.ename,v_deptno,:new.sal);
END trig_view; (4)创建一个系统级别触发器,记录所有用户的数据库访问时间。
将每个用户的登录信息写入temp_table表中。
CREATE OR REPLACE TRIGGER log_user_connection
AFTER LOGON ON DATABASE
BEGIN
INSERT INTO scott.temp_table VALUES (user,sysdate);
END log_user_connection; 4.如何在 Oracle中实现类似自动增加 ID的功能
Oracle本身并未提供像 Access中的自动编号类型,但同样也可以实现类似自动增加 ID的功能,即字段值自动增长并自动插入到字段中,这时需要借助序列和触发器共同来实现。
例如,水果表“fruit”中有两个字段“num”、“name”,分别记录序号和水果的名称,第一个字段值随着第二个字段值的插入自动按顺序添加并插入。
CREATE TABLE fruit
( num VARCHAR2(10) PRIMARY KEY,
name VARCHAR2(10)
);
首先,创建一个序列 NUM。
CREATE SEQUENCE num
INCREMENT BY 1
START WITH 1 MAXVALUE 9999 MINVALUE 1
NOCYCLE
CACHE 20
ORDER;
其次,创建一个触发器。
CREATE TRIGGER fruit_tri
BEFORE INSERT ON fruit
FOR EACH ROW
BEGIN
SELECT TO_CHAR(NUM.nextval) INTO :NEW.num FROM DUAL;
//将序列的下一个取值存储到 fruit 表中的“name”字段,DUAL 为系统表
END;
插入新记录后再查看“fruit”表中的现有记录。
INSERT INTO fruit(name) VALUES(‘菠萝’);
SELECT * FROM fruit;
数据库SQL基本操作的更多相关文章
- 通过sql语句对MySql数据库的基本操作
一.数据库的基本操作 CREATE DATABASE mybookstore; DROP DATABASE mybookstore; 二.表的基本操作 1.创建表 insert into 表名(字段名 ...
- 大数据学习day26----hive01----1hive的简介 2 hive的安装(hive的两种连接方式,后台启动,标准输出,错误输出)3. 数据库的基本操作 4. 建表(内部表和外部表的创建以及应用场景,数据导入,学生、分数sql练习)5.分区表 6加载数据的方式
1. hive的简介(具体见文档) Hive是分析处理结构化数据的工具 本质:将hive sql转化成MapReduce程序或者spark程序 Hive处理的数据一般存储在HDFS上,其分析数据底 ...
- 图数据库orientDB(1-1)SQL基本操作
SQL基本操作 1.新增VerTex CREATE VERTEX V SET name="user01",sex="M",age="25"; ...
- sql 基本操作
SQL基本操作 一数据类型1整数型 int2精确数值型 decimal(n,p)n为总位数,p为小数位数3浮点型 float4字符型char(n)n最大为4,varchar(n)5日期型datat ...
- MYSQL基础笔记(二)-SQL基本操作
SQL基本操作 基本操作:CRUD,增删改查 将SQL的基本操作根据操作对象进行分类: 1.库操作 2.表操作 3.数据操作 库操作: 对数据库的增删改查 新增数据库: 基本语法: Create da ...
- 【转】Android开发之数据库SQL
android中的应用开发很难避免不去使用数据库,这次就和大家聊聊android中的数据库操作. 一.android内的数据库的基础知识介绍 1.用了什么数据库 android中采用的数据库是SQLi ...
- PostgreSQL自学笔记:3 数据库的基本操作
3 数据库的基本操作 3.1 创建数据库 3.1.1 使用对象浏览器创建数据库 [Server] -> PostgreSQL 9.6 -> 数据库,右击 -> 创建 通常: 数据库: ...
- 数据库_7_SQL基本操作——表操作
SQL基本操作——表操作 建表的过程就是声明列的过程. 表与字段是密不可分的. 一.新增数据表 create table [if not exists] 表名( 字段名字 数据类型, 字段名字 数据类 ...
- 数据库_6_SQL基本操作——库操作
SQL基本操作——库操作:对数据库的增删改查 一.新增数据库(创建) 基本语法:create database 数据库名字 [库选项]: 库选项用来约束数据库,分为两个选项:1.字符集设定:chars ...
随机推荐
- .net线程池内幕
本文通过对.NET4.5的ThreadPool源码的分析讲解揭示.NET线程池的内幕,并总结ThreadPool设计的好与不足. 线程池的作用线程池,顾名思义,线程对象池.Task和TPL都有用到线程 ...
- 背水一战 Windows 10 (20) - 绑定: DataContextChanged, UpdateSourceTrigger, 对绑定的数据做自定义转换
[源码下载] 背水一战 Windows 10 (20) - 绑定: DataContextChanged, UpdateSourceTrigger, 对绑定的数据做自定义转换 作者:webabcd 介 ...
- oracle函数大全(转载)
F.1字符函数--返回字符值 这些函数全都接收的是字符族类型的参数(CHR除外)并且返回字符值.除了特别说明的之外,这些函数大部分返回VARCHAR2类型的数值.字符函数的返回类型所受的限制和基本数据 ...
- Apache的初中级面试题
--- 原文:[关于Apache的25个初中级面试题](http://www.oschina.net/translate/apache-interview-questions) Apache 求职面试 ...
- JVM监控工具介绍
JVM监控工具介绍 VisualVM是一种集成了多个JDK命令行工具的可视化工具,它能为您提供强大的分析能力.所有这些都是免费的!它囊括的命令行工具包括jps,jstat,jmap,jinfo,jst ...
- HTML5漂亮实用的电子书
效果体验:http://hovertree.com/texiao/html5/2.htm 点击这里下载 支持多种系统Mac,PC,Android,iPhone,iPad和Windows Phone 支 ...
- Javascript实现格式化输出
前两天看面试题,其中有一道要实现js的格式化输出,具体给出的是: Javascript实现格式化输出,比如输入999999999,输出为999,999,999 我的实现方式是 function for ...
- 网站 robots.txt 文件编写
网站 robots.txt 文件编写 Intro robots.txt 是网站根目录下的一个纯文本文件,在这个文件中网站管理者可以声明该网站中不想被robots访问的部分,或者指定搜索引擎只收录指定的 ...
- iOS笔记之NSSet
一.简介 NSSet到底什么类型,其实它和NSArray功能性质一样,用于存储对象,属于集合: NSSet , NSMutableSet类声明编程接口对象,无序的集合,在内存中存储方式是不连续的, ...
- SharePoint 2013 Search 配置总结
前言:SharePoint 2013集成了Fast搜索以后,搜索的配置有了些许改变,自己在配置过程中,也记录下了一些入门的东西,希望能够对大家有所帮助. 1.配置搜索服务,首先需要启用搜索功能,基本思 ...