数据库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 ...
随机推荐
- ASP.NET Core开发-如何配置Kestrel 网址Urls
ASP.NET Core中如何配置Kestrel Urls呢,大家可能都知道使用UseUrls() 方法来配置. 今天给介绍全面的ASP.NET Core 配置 Urls,使用多种方式配置Urls. ...
- centos 系统下安装FastDFS+nginx+fastdfs-nginx-module安装配置
前言: 以前的项目上传的文件都是保存到本地或者是局域网内的共享文件夹下,由于数据量,服务器的负载均衡(分机的某些图片无法访问的问题处理)等因素的情况下,就想到用fastdfs来文件管理,花了几天时间硬 ...
- thinkphp怎么设置输入网址直接进入首页
1.设置apache服务器的时候,文件的位置要写包含index.php的那个主文件夹. 2.apache和thinkphp默认index.html是作为网站的默认首页,所以在浏览器端可以直接输入网址进 ...
- div悬浮
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- 从零开始学 Java - Spring AOP 实现用户权限验证
每个项目都会有权限管理系统 无论你是一个简单的企业站,还是一个复杂到爆的平台级项目,都会涉及到用户登录.权限管理这些必不可少的业务逻辑.有人说,企业站需要什么权限管理阿?那行吧,你那可能叫静态页面,就 ...
- VS2015开发Android,自带模拟器无法调试、加载程序,算是坑吗
VS2015出来后,确定变化很大,什么android.ios的,不在话下.对于我这样传统型的人,也第一时间试用了一下(vs2003->vs2008->vs2012->vs2015). ...
- 简单实用的二级树形菜单hovertree
原创 hovertree是一个仿京东的树形菜单jquery插件,暂时有银色和绿色两种. 官方网址:http://keleyi.com/jq/hovertree/欢迎下载使用 查看绿色效果:http:/ ...
- 实现bootstrap布局的input输入框中的图标点击功能
使用bootstrap布局可以在input的输入框中添加譬如登录名输入框中的一键清除图标和密码输入框中显示密码的小眼睛图标.如下图: 但是在将图标放入input输入框中,这些小图标是无法获得点击事件的 ...
- js中Unicode转义序列
将某一中文字符转义,可采取在线工具进行转义,http://tool.chinaz.com/tools/unicode.aspx "哈哈" ==="\u54c8\u54c8 ...
- Inplace Search on document libraries and lists is not working
[http://sharepointfarmer.com/inplace-search-on-document-libraries-and-lists-is-not-working/] I ran i ...