oracle数据库练习题

sqlplus sys/111111 as sysdba

show parameter name;

–建立test表空间

create tablespace test datafile ‘D:\app/test.dbf’ size 50m maxsize 1g autoextend on;

show parameter name; –显示数据库名,实例名等

show parameter db_name; –显示数据库名

show parameter instance;

select *from v$database;

–查看实例信息

select *from v$instance;

–查看实例名

select name from v$database;

select instance_name from v$instance;

show parameter instance

–查看用户

select *from dba_users;

–建用户授权

create user test identified by 111111;

grant connect,resource to test;

conn test/111111;

drop user test cascade;

conn /as sysdba;

drop user test cascade;

–test有connect的管理权限,可将connect 权限赋给另一个人

create user test identified by 111111;

grant connect,resource to test with admin option;

–查询系统权限

select *from sys.dba_sys_privs; //查询所有用户权限

select *from user_sys_privs;//查询sys用户权限

–回收权限

show user;

conn /as sysdba;

revoke connect from test;

–解锁用户

sqlplus sys/111111 as sysdba

show user;

conn scott/tiger;

show user; //显示没有用户

alter user scott account unlock; //退出重新登录,在有用户的时候登

conn scott/tiger; //连接之后输入新密码

–解锁后用plsql登录 scott/tiger 用户

select *from user_tables; //查询表名

select * from dept; //dept部门表

select emp.* from emp; //emp员工表

select *from emp;

select *from bonus; //bonus奖金表

select *from salgrade; //收入等级表

select * from dept;

select distinct dname from dept;

select dname from dept;

select empno,ename from emp ;

select empno,ename from emp where ename = ‘SMITH’;

select ename from emp where ename = ‘SMITH’;

select *from emp where empno between 7369 and 7830;

select *from emp where empno like ‘%99’;

select empno,ename from emp where ename = ‘SMITH’;

select *from emp where empno like ‘%56%’;

select *from emp where empno in(7499,8000);

select *from emp where empno in(7499,7839);

select *from emp where empno is null;

select *from emp where empno is not null;

select *from emp where empno >= ‘7521’;

select *from emp where rownum <= 5;

select empno,ename,sal+300 from emp where rownum <= 10;

select empno as0000 from emp;

select empno www from emp;

select empno as wwww from emp where rownum <= 10;

select *from emp;

select empno ,ename,job,mgr aaaa from emp order by empno desc;

select deptno from emp group by deptno;

select empno,ename||’m’ from emp where rownum <= 5;

select empno,ename||’+’||sal from emp;

select deptno,max(sal) from emp group by deptno;

select deptno,substr(ename,5) from emp where rownum <= 5;

select *from emp;

insert into emp(empno,deptno) values(7368,10);

insert into emp(empno,deptno) values(7368,50); //部门表的部门编号只有10,20,30,报错

delete from dept where deptno = 10; //删除父表中的记录,子表中有记录报错

1.查询姓名首字母为A或第二个字符为A的所有员工信息

//错误

select *from emp;

select *from emp where substr(ename,1,1) = ‘a’ or substr(ename,2,1)=’a’;

select *from emp where ename like ‘A%’ or like ‘_A%’;

//修正

select *from emp;

select *from emp where substr(ename,1,1) = ‘A’ or substr(ename,2,1)=’A’;

select *from emp where ename like ‘A%’ or ename like ‘_A%’;

2.查询部门20,30 中的岗位不是”CLERK”或”SALESMAN”的所有员工信息

select *from emp where job not in(‘CLERK’);

select *from emp where job not in(‘SALESMAN’);

select *from emp;

select *

from emp

where job<>’CLERK’

and job<>’SALESMAN’

and deptno in (20, 30);

select *

from emp

where job not in (‘CLERK’,’SALESMAN’)

and deptno in (20, 30);

3.查询工资在2500-3500之间,1981年入职,没有奖金的所有员工信息

select *from emp where sal between 2500 and 3500 and to_char(hiredate,’YYYY-MM-DD’) like ‘1981%’ and comm is null;

–用了子查询还有extract函数

select *from (select *from emp where sal between 2500 and 3500 and comm is null)where extract(year from hiredate) = ‘1981’;

select *from emp where extract (year from hiredate) = ‘1981’;

4.查询比平均员工工资高的员工信息

//错误

select *from emp where sal > avg(sal);

//正确

select *from emp where sal > (select avg(sal) from emp);

select avg(sal) from emp; //是子查询

5.查询平均工资高于2000的部门信息 //select avg(sal) from emp 是 所有人平均工资

–1.先找到平均工资大于两千的部门编号,即每个部门的平均工资大于两千的先找出来

select deptno,avg(sal) from emp by deptno having avg(sal) >2000

–2.根据部门编号查找部门信息

select deptno,dname,loc from dept where deptno in(select deptno from emp group by deptno having avg(sal) >2000 );

6.查询出WARD的工作所在地

//这边用in不太好,in是个范围,已经确定了姓名,用等号也不太好

select loc from dept where deptno in (select deptno from emp where ename = ‘WARD’);

–用两个表的自然链接

select ename,dept.loc from dept,emp where emp.deptno = dept.deptno and ename = ‘WARD’;

7.查询出工资比ADAMS高的所有人的姓名、部门、所在地

select ename,dname,loc from dept,emp where emp.deptno = dept.deptno and emp.sal > (select sal from emp where ename = ‘ADAMS’ );

8.–查询工资排名第7的员工信息

//将员工工资先降序排列,查出前7条数据,取前7条数据中的最小工资

select sal from emp order by sal desc;

select *from emp where sal = (select min(sal) from (select *from emp order by sal desc)where rownum <= 7 )

//利用minus将两个降序结果集相减,union则是将两个结果集相并

select *from emp order by sal desc;

select sal from (select *from emp order by sal desc )where rownum <= 7;

select sal from (select *from emp order by sal desc )where rownum <= 6;

select *

from emp

where sal = (select sal

from (select * from emp order by sal desc)

where rownum <= 7 minus

select sal

from (select * from emp order by sal desc)

where rownum <= 6);

//oracle函数

select ename,to_char(hiredate,’YYYY_MM_DD HH:MM:SS’) from emp;

select ename,hiredate from emp; //显示日历格式

select to_date(‘2016-11-23′,’YYYY-MM-DD’) from dual;

select sysdate,add_months(sysdate,3),add_months(sysdate,2)from dual;

select sysdate,last_day(sysdate),last_day(sysdate)+1 from dual;

select

months_between(’17-9月-2013′,’17-9月-2013′)as 第一个结果是,

months_between(’17-10月-2013′,’17-8月-2013′)as 第二个结果是,

months_between(’17-8月-2013′,’17-10月-2013′)as 第三个结果是

from dual;

select

next_day(sysdate,’星期一 ‘)as第一个结果是,

next_day(’18-9月-2013′,’星期一’)as第二个结果是

from dual;

1.查询与部门20岗位不同的员工姓名、工资 (岗位是job)

//错误

select ename,sal,deptno from emp where deptno != 20;

select ename,sal,deptno from emp where deptno not in (select deptno from dept where deptno = 20);

//正确

select ename,sal,job from emp where job not in (select job from emp where deptno = 20);

2.查询与SMITH部门、岗位完全相同的员工姓名、工作、工资

select *from emp;

select deptno,job from emp where ename = ‘SMITH’

select ename, job, sal

from emp

where deptno = (select deptno from emp where ename = ‘SMITH’)

and job = (select job from emp where ename = ‘SMITH’)

and ename <> ‘SMITH’

–查询emp表中的所有信息

select *from emp;

–显示emp表的员工姓名和工资

select ename,sal from emp;

–查询emp表中的部门编号为20的并且sal(工资)大于3000的所有员工信息

select *from emp where deptno = 20 and sal > 3000;

–查询emp表中部门编号为20的或者sal(工资)大于3000的所有员工信息

select *from emp where deptno = 20 or sal > 3000;

–使用between and查询工资在2000和4000之间的员工(用and重新实现)

select *from emp where sal between 2000 and 4000;

select *from emp;

select sal from emp where deptno = 20

select *from emp where empno < any (select empno from emp where deptno = 20) and deptno != 20;

select *from emp where empno < all (select empno from emp where deptno = 20) and deptno != 20;

–等值链接 (deptno对于emp表是外键,对于dept表是主键)

select empno,emp.deptno,sal from emp,dept where emp.deptno = dept.deptno;

–内连接 即等值连接//这些连接在照片上

select empno,emp.deptno,dept.deptno from emp,dept where emp.deptno = dept.deptno;

–左外连接

select empno,emp.deptno,loc from emp,dept where emp.deptno = dept.deptno(+);

select empno,e.deptno,loc from emp e left join dept d on e.deptno = d.deptno;

–右外连接

select empno,emp.deptno,loc from emp,dept where emp.deptno(+) = dept.deptno;

select empno,e.deptno,loc from emp e right join dept d on e.deptno = d.deptno;

left join 与 right join多用于生成的视图上

–全连接

–笛卡尔积–不带条件(效率十分低下,行数为几个表行数之积)

select empno,emp.deptno,sal from emp,dept;

–使用in查询部门编号10,20的所有员工

select *from emp where deptno in(10,20);

–使用like查询所有名字中包括w的员工信息

//错误,W是大写的

select *from emp where ename like ‘%w%’

select *from emp where ename like ‘%w’ or ename like ‘w%’ or ename like ‘%w%’;

//正确

select *from emp where ename like ‘%W’ ;

–使用like查询所有员工名字中第二个字母为w的员工信息

select *from emp where ename like ‘_W%’;

–查询所有员工信息并按照部门编号和工资进行排序

//错误

select *from emp order by deptno and emp order by sal;

//正确

select *from emp order by deptno ,sal;

select ename,deptno,sal from emp order by 2,3; //先对2进行排序,也就是对deptno进行排序

select ename,deptno,sal from emp order by sal;

select deptno,sal from emp order by 1,2;

–显示所有员工工资上浮%20的结果

select *from emp;

select ename,sal*1.2 new_sal, sal from emp;

–显示emp表的员工姓名以及工资和奖金的和

//错误

select ename ,sal,comm,sal+comm sum from emp;

select ename ,sal,comm,sal||’+’||comm sum from emp;

//正确

select ename ,sal,comm,sal||comm sum from emp;

select ename ,sal,comm,sal+nvl(comm,0) sum from emp; //nvl转换函数

–显示dept表的内容,使用别名将表头转成中文显示 (表头:deptno,dname,loc)

select *from dept;

select deptno 部门编号,dname 部门名字,loc 工作地点 from dept;

–查询员工姓名和工资,并按工资从小到大排序

select ename,sal from emp order by 2;

–查询员工姓名和雇佣日期,并按雇佣日期排序,后雇佣的先显示

select *from emp;

select ename ,to_char(hiredate,’YYYY-MM-DD’) from emp order by 2 desc;

select ename ,hiredate from emp order by 2 desc;

–查询员工信息,先按部门标号从小到大排序,再按雇佣时间的先后排序

select *from emp order by deptno,to_char(hiredate,’YYYY-MM-DD’);

select *from emp order by deptno,hiredate;

–11列出薪金高于公司平均工资的所有员工,所在部门,上级领导,公司的工资等级//所有员工是所有员工信息吗

select * from emp;

select e1.ename, dname, e2.ename mgr, grade

from emp e1, dept, emp e2, salgrade

where e1.mgr = e2.empno(+)

and e1.deptno = dept.deptno

and e1.sal > (select avg(sal) from emp)

and e1.sal between losal and hisal;

select * from emp;

–12列出与scott从事相同工作的所有员工及部门名称 //没有用到什么为空,用等值连接即可

select * from dept;

–用等值连接

select distinct ename, dname, job

from emp, dept

where emp.deptno = dept.deptno

and job = (select job from emp where ename = ‘SCOTT’);

–13列出薪金大于部门30中的任意员工的薪金的所有员工的姓名和薪金

/ / 错误

select ename, sal

from emp

where sal > (select sal from emp where deptno = 30) / / 正确

select ename, sal

from emp

where sal > (select min(sal) from emp where deptno = 30);

/ / 可以用any

–14列出薪金大于部门30中的全部员工的薪金的所有员工的姓名和薪金,部门名称 //用any和all实现

select ename, sal, dname, emp.deptno

from emp, dept

where emp.deptno = dept.deptno

and sal > (select max(sal) from emp where deptno = 30);

–15列出每个部门的员工数量,平均工资

/ / 正确

select dept.deptno, count(ename), trunc(avg(sal + nvl(comm, 0)))

from emp, dept

where dept.deptno = emp.deptno(+)

group by dept.deptno;

/ / 错误

select dept.deptno, count(*), avg(sal)

from emp, dept

where dept.deptno = emp.deptno(+)

group by dept.deptno;

/ / 用left join为什么错

–16列出每个部门的员工数量,平均工资和平均服务期限(月)

select * from emp;

select deptno,

count(*),

trunc(avg(sal + nvl(comm, 0))),

/ / trunc函数截取小数 trunc(avg(sysdate – hiredate) / 30)

from emp

group by deptno;

–17.列出各种工作的最低工资及从事工资最低工作的雇员名称

select job, min(sal)

from emp

group by job

select * from emp;

/ / 如果emp表里有两个数据是800,a表里也有两个数据是800,不加 a.job = emp.job这个条件, 会输出4条数据

select ename, a.*

from (select job, min(sal) sal from emp group by job) a, emp

where a.sal = emp.sal

and a.job = emp.job;

–18求出部门名称带字符’s’的部门员工,工资合计,部门人数

/ / 错误

select dept.deptno, count(ename)

from emp, dept

where emp.deptno(+) = dept.deptno

group by dept.deptno;

select ename, sal + nvl(comm, 0), a.count

from emp,

(select dept.deptno, count(ename) count

from emp, dept

where emp.deptno(+) = dept.deptno

group by dept.deptno) a,

dept

where dept.deptno = emp.deptno(+)

and a.deptno = dept.deptno

and dept.dname like ‘%s%’;

/ / 正确

select * from emp;

select * from dept;

select dname,

dept.deptno,

ename,

nvl2(comm, sal + comm, sal) 工资合计,

a.count 部门人数

from emp,

(select deptno, count(ename) count from emp group by deptno) a,

dept

where dept.deptno = emp.deptno(+)

and a.deptno(+) = emp.deptno

and dept.dname like ‘%S%’;

–19.求出部门平均工资以及等级

select * from salgrade;

select avg(sal) sal, deptno

from emp

group by deptno

select grade, a.sal

from salgrade,

(select avg(sal) sal, deptno from emp group by deptno) a

where a.sal between losal and hisal;

–20不使用函数查询工资最高人的信息

/ / 错误

select *

from emp

where sal = (select sal

from (select sal from emp order by sal desc)

where rownum = 2);

select sal from emp order by sal desc;

select sal from (select sal from emp order by sal desc) where rownum <= 5;

/ / 正确

select * from emp where sal >= all (select sal from emp);

–21求出平均工资最高的部门名称

/ / 错误

select avg(sal), e.deptno from emp e group by e.deptno;

select dname

from emp, (select avg(sal) b, e.deptno from emp e group by e.deptno) a

where emp.deptno = a.deptno

and emp.deptno in (select a.deptno from a where a.b = max(a.b));

select dname

from dept

where deptno =

(select deptno

from (select deptno from emp group by deptno order by avg(sal) desc)

where rownum = 1);

–22求平均工资的等级最低的部门名称//学会用with as

select * from salgrade;

–求出部门平均工资以及等级

select a.deptno, grade, a.sal

from salgrade, (select avg(sal) sal, deptno from emp group by deptno) a

where a.sal between losal and hisal;

—-等级最低

select min(grade)

from (select a.deptno, grade, a.sal

from salgrade,

(select avg(sal) sal, deptno from emp group by deptno) a

where a.sal between losal and hisal) b;

–等级最低的部门编号

select deptno

from (select a.deptno, grade, a.sal

from salgrade,

(select avg(sal) sal, deptno from emp group by deptno) a

where a.sal between losal and hisal) b

where b.grade =

(select min(grade)

from (select a.deptno, grade, a.sal

from salgrade,

(select avg(sal) sal, deptno from emp group by deptno) a

where a.sal between losal and hisal) b);

–依据部门编号查找部门姓名

/ / 错误

select dname

from dept,

(select a.deptno, grade, a.sal

from salgrade,

(select avg(sal) sal, deptno from emp group by deptno) a

where a.sal between losal and hisal) b

where dept.deptno = b.deptno

and dept.deptno =

(select b.deptno from b where b.grade = (select min(grade) from b));

/ / 正确

select dname

from dept

join (select deptno, grade

from (select deptno, avg(sal) avg_sal from emp group by deptno) t

join salgrade on (t.avg_sal between salgrade.losal and

salgrade.hisal)) t on dept.deptno = t.deptno

where t.grade = (select min(grade)

from (select avg(sal) avg_sal from emp group by deptno) t

join salgrade on (t.avg_sal between salgrade.losal and

salgrade.hisal));

–23部门经理人中平均工资最低的部门名称

select dname

from (select deptno, avg(sal) avg_sal

from emp

where empno in (select mgr from emp)

group by deptno) t

join dept on t.deptno = dept.deptno

where avg_sal = (select min(avg_sal)

from (select avg(sal) avg_sal

from emp

where empno in (select mgr from emp)

group by deptno) t);

–创建视图

–如果创建视图的时候出现权限不足,则进行授权操作 show user; //出现sys用户 grant create view to scott;

create or replace view empdetail as

select empno, ename, job, hiredate, emp.deptno, dname

from scott.emp

join scott.dept on emp.deptno = dept.deptno with read only;

select * from empdetail;

select * from empdetail;

drop view empdetail;

–创建序列

create sequence seq_test start with 1 increment by 1 cache 30;

select sql_test.nextval from dual;

select sql_test.nextval from dual;

.. .

–创建序列

select rowid, emp.* from emp;

/ / rowid数据块的唯一标识

— Create/Recreate indexes

create index uk on TEXT(test_name);

/ / 创建索引(normal索引) create index UK on TEXT(test_name, test_id) ; / / 创建组合索引

–plsql块

declare i integer;

begin

i := 1;

dbms_output.put_line(i);

end;

— Created on 2017/11/3 by ZHAOXIAOFENG

declare

— Local variables here

i integer;

begin

— Test statements here

for i in 1 .. 3 loop

dbms_output.put_line(i);

end loop;

end;

declare

— Local variables here

sname VARCHAR2(20) := “jerry”;

begin

— Test statements here

sname := sname || “and tom”;

dbms_output.put_line(sname);

end;

/ / 在命令窗口输入的话加set serveroutput on set serveroutput on declare sname VARCHAR2(20) DEFAULT “jerry”;

— Local variables here

begin

select ename into sname from scott.emp where empno = 7934;

— Test statements here

dbms_output.put_line(sname);

end;

/ / 变量初始化时,可以使用DEFAULT关键字对变量进行初始化 / / 使用select .. .into语句对 变量sname赋值, 要求查询的结果必须是一行, 不能是多行或者没有记录,用游标的方式对多行进行处理

— Created on 2017/11/3 by ZHAOXIAOFENG

declare

— Local variables here

pi constant number := 3.14;

r number default 3;

area number;

i integer;

begin

— Test statements here

area := pi * r * r;

dbms_output.put_line(area);

end;

/*常量用constant

数据块常用数据类型

varchar2,number,date,boolean//布尔

引用数据库一行作为数据类型,即record类型(是plsql附加的数据类型)*/

— %ROWTYPE类型

declare

myemp scott.emp%ROWTYPE; –myemp和soctt.emp这张表的数据类型一样

begin

–select into结果查询必须是一行,不能是多行

select * into myemp from scott.emp where empno = 7934;

–查询过后myemp变成了一条记录即 select * from scott.emp where empno = 7934;

dbms_output.put_line(myemp.ename);

dbms_output.put_line(myemp.deptno);

dbms_output.put_line(myemp.sal);

end;

–%type(某列的类型)

declare

sal scott.emp.sal%type;

mysal number(4) := 3000;

totalsal mysal%type;

begin

select SAL into sal from scott.emp where empno = 7934;

totalsal := sal + mysal;

dbms_output.put_line(totalsal);

end;

–查询JAMES工资,如果大于900,则发奖金800

declare

newsal scott.emp.sal %type;

begin

select sal into newsal from scott.emp where ename = ‘JAMES’;

dbms_output.put_line(newsal);

if newsal > 900 then

update scott.emp set comm = 800 where ename = ‘JAMES’;

end if;

select comm INTO newsal from scott.emp where ename = ‘JAMES’;

dbms_output.put_line(newsal);

commit;

end;

–if-then-else-endif

declare

newsal scott.emp.sal %type;

begin

select sal into newsal from scott.emp where ename = ‘JAMES’;

dbms_output.put_line(newsal);

if newsal < 900 then

update scott.emp set comm = 800 where ename = ‘JAMES’;

else

update scott.emp set comm = 400 where ename = ‘JAMES’;

end if;

select comm INTO newsal from scott.emp where ename = ‘JAMES’;

dbms_output.put_line(newsal);

commit;

end;

–if-then-elsif-then-else-end if

declare

newsal scott.emp.sal %type;

begin

select sal into newsal from scott.emp where ename = ‘JAMES’;

dbms_output.put_line(newsal);

if newsal > 1500 then

update scott.emp set comm = 800 where ename = ‘JAMES’;

elsif newsal > 900 then

update scott.emp set comm = 400 where ename = ‘JAMES’;

else

update scott.emp set comm = 200 where ename = ‘JAMES’;

end if;

select comm INTO newsal from scott.emp where ename = ‘JAMES’;

dbms_output.put_line(newsal);

commit;

end;

–if-then-elsif-then-else-end if

declare

newsal scott.emp.sal %type;

begin

select sal into newsal from scott.emp where ename = ‘JAMES’;

dbms_output.put_line(newsal);

if newsal >1500 then

update scott.emp set comm = 800

where ename = ‘JAMES’;

elsif newsal > 900 then

update scott.emp set comm = 400

where ename = ‘JAMES’;

else

update scott.emp set comm = 200

where ename = ‘JAMES’;

end if;

select comm INTO newsal from scott.emp where ename = ‘JAMES’;

dbms_output.put_line(newsal);

commit;

end;

–case 语句

declare

v_grade char(1):= upper(‘&p_grade’); –upper函数用来输入一个变量

begin

case v_grade

when ‘A’ then

dbms_output.put_line(‘Excellent’);

when ‘B’ then

dbms_output.put_line(‘Good’);

when ‘C’ then

dbms_output.put_line(‘Very Good’);

else

dbms_output.put_line(‘No such grade’);

end case;

end;

–loop循环控制

–1+2+..+100

declare

i number(3) := 0;

sumresult number := 0;

begin

loop

i := i + 1;

sumresult := sumresult + i;

if i >= 100 then

exit;

end if;

end loop;

dbms_output.put_line (‘result is :’||to_char(sumresult));

end;

–while 循环

declare

i number(3) := 0;

sumresult number := 0;

begin

while i < 100 loop

i := i + 1;

sumresult := sumresult + i;

end loop;

dbms_output.put_line (‘result is :’||to_char(sumresult));

end;

–for 循环

declare

i number(3) := 0;

sumresult number := 0;

begin

for i in 1..100 loop

sumresult := sumresult + i;

end loop;

dbms_output.put_line (‘result is :’||to_char(sumresult));

end;

begin

update scott.emp set sal=sal+100 where empno =7876;

if SQL%found then

dbms_output.put_line(‘成功修改雇员工资’);

else

dbms_output.put_line(‘修改雇员工资失败’);

end if;

end;

–动态sql

/*declare

sql_stmt varchar2(200); –动态sql语句

emp_id number(4) :=7566;

salary number(7,2);

dept_id number(2) :=90;

dept_name varchar2(14) := ‘personnel’;

location varchar2(13) :=’DALLAS’;

emp_rec scott.emp%rowtype;

begin

–无子句的execute immediate

execute immediate ‘create table a(id number,amt number)’;

–using子句中的execute immediate

sql_stmt := ‘insert into scott.dept values(:1,:2,:3)’;

execute immediate sql_stmt

using dept_id,dept_name,location;–用using 进行赋值

commit;

–into子句的execute immediate

sql_stmt := ‘select *from scott.emp where empno = :id’;

execute immediate sql_stmt

into emp_rec

using emp_id;

–returning into 子句中的execute immediate

sql_stmt := ‘update scott.emp set sal = 2000 where empno = :1 returning sal into :2’;

execute immediate sql_stmt

using emp_id

returning into salary;

execute immediate ‘delete from scott.dept where deptno =: num’

using dept_id;

end;*/

//三种循环输出结果集

–用for 循环的好处不需要显示的open,fetch,close (游标就是指针,去不停地加1)

/*declare

–类型定义

cursor c_job is select empno,ename,job,sal from emp where job=’MANAGER’;

–定义一个游标变量v_cinfo c_emp%ROWTYPE ,该类型为游标c_emp中的一行数据类型

c_row c_job%rowtype;

begin

for c_row in c_job loop

dbms_output.put_line(c_row.empno||’-‘||c_row.ename||’-‘||c_row.job||’-‘||c_row.sal);

end loop;

end;*/

–loop循环,fetch游标

/*declare

cursor cur is select * from emp;–声明游标

userinfo emp%rowtype;

begin

open cur;–打开游标

loop –指针不停地加

exit when cur%notfound; –当找不到的时候就退出

fetch cur into userinfo;–找到游标将游标变量插入到userinfo中

dbms_output.put_line(‘user id:’ || userinfo.empno || ‘-‘ ||

‘user name:’ || userinfo.ename);

end loop;–emp表行数结束,end loop

exception

when others then

dbms_output.put_line(sqlerrm);

close cur;

end;*/

–while 循环

declare

–游标声明

cursor test is

–select语句

select * from emp;

–指定行指针

userinfo emp%rowtype;

begin

–打开游标

open test;

–找到游标将游标变量插入到userinfo中

fetch test into userinfo;

–测试是否有数据,并执行循环

while test%found loop

dbms_output.put_line(‘部门编号:’ || userinfo.empno || ‘-‘ ||

‘姓名’ || userinfo.ename);

–给下一行喂数据

fetch test into userinfo;

end loop;

close test;

end;

–创建存储过程 on //进行输出

set serveroutput on

create or replace procedure proc(i in int) as

a varchar(20);

begin

for j in 1 .. i loop

a := a || ‘*’;

dbms_output.put_line(a);

end loop;

end;

/

set serveroutput on

exec proc(5);

–在命令窗口显示 in

set serveroutput on

create or replace procedure proc(i out int)

as begin

i:=100;

dbms_output.put_line(i);

end;

/

declare a int;

begin

proc(a);

end;

/

–in out 类型

create or replace procedure proc(num1 in out int,num2 in out int)

as

temp int;

begin

temp := num1;

num1 := num2;

num2 := temp;

end;

/

declare

num1 int:=100;

num2 int:=200;

begin

proc(num1,num2);

dbms_output.put_line(‘num1是’||num1);

dbms_output.put_line(‘num2是’||num2);

end;

/

–函数

create or replace function fun1 return varchar2

is

begin

return ‘hello,world!’;

end;

/

set serveroutput on

declare

ss varchar2(20);

begin

ss:= fun1;

dbms_output.put_line(ss);

end;

/

drop function function_name;

–触发器

create or replace trigger tri1

after insert

on emp

for each row –每行都触发触发器

begin

dbms_output.put_line(‘触发器执行了’);

end;

/

insert into emp(empno) values(7379);

–插入值为负,停止插入

create or replace trigger tri2

before insert

on emp

for each row –每行都触发触发器

begin

if :new.empno<0 then–new.empno是个变量,所以前面加:

raise_application_error(-20001,’员工编号为负,不能插到表中!’);

end if;

end;

/

insert into emp(empno) values(-1);

dual系统表

–练习

–1.自定义输入任意员工编号,输出该员工编号、姓名、工资、部门、名称、所在地

declare

m_empno number;

m_ename varchar2(20);

m_sal number;

m_dname varchar2(50);

m_loc varchar2(30);

i number;

begin

i :=&i;

select empno,ename,sal,dname,loc into m_empno,m_ename,m_sal,m_dname,m_loc from emp

join dept on dept.deptno = emp.deptno where empno = i;

–dbms_output.put_line(‘编号’||m_empno||’姓名’||m_ename||’工资’||m_sal||’部门名称’||m_dname||’所在地’||m_loc);

dbms_output.put_line(m_empno || ‘ ‘ ||m_ename || ‘ ‘ ||m_sal || ‘ ‘ ||m_dname || ‘ ‘ ||m_loc);

end;

–2.自定义输入任意员工编号,如果该员工入职时间大于10年,则奖金加1W,如果大于5年,奖金加5000,否则奖金不加 //考虑如何正常输出奖金

–最终输出员工的编号、姓名、入职时间、原奖金、现奖金

declare

m_empno number;

m_ename varchar2(20);

m_hiredate date;

m_comm number;–原奖金

m_nowcomm number;–现奖金

m_year int;

i number;

begin

i :=7369;

select empno,ename,hiredate,comm into m_empno,m_ename,m_hiredate,m_comm from emp where empno = i;

select months_between(sysdate, hiredate) into m_year from emp where empno = i;–总的月份

dbms_output.put_line(m_empno||’ ‘||m_ename||’ ‘||m_hiredate||’ ‘||m_comm||’ ‘||m_nowcomm);

if m_year /12 > 10 then

update emp set comm = nvl(comm,0)+10000 where empno = i;–update语句的写法注意

elsif m_year/12 >=5 and m_year/12 <= 10 then

–elsif m_year/12 between 5 and 10 then

update emp set comm = nvl(comm,0)+5000 where empno = i;

end if;

–else null

–commit;

select comm into m_nowcomm from emp where empno = i;

dbms_output.put_line(m_empno||’ ‘||m_ename||’ ‘||m_hiredate||’ ‘||m_comm||’ ‘||m_nowcomm);

end;

–5.对每位员工的薪水进行判断,如果该员工薪水高于其所在部门的平均薪水,工资减50,显示原工资和现在的工资

SQL> set serveroutput on

SQL>

SQL> declare

2 m_empno emp.empno%type :=’&i’;

3 avgsal number;

4 now_sal number;

5 rt_emp emp%rowtype;–行类型

6 begin

7 select *into rt_emp from emp where empno = m_empno;

8 select avg(sal) into avgsal from emp group by emp.deptno having emp.deptno = rt_emp.deptno;

9 dbms_output.put_line(‘员工编号’||m_empno||’原工资’||rt_emp.sal||’现工资’||now_sal||’平均薪水’||avgsal);

10 if rt_emp.sal > avgsal then

11 –update emp set sal = sal – 50 where emp.empno =m_empno;

12 update emp set sal = rt_emp.sal – 50 where emp.empno =m_empno;

13 end if;

14 select sal into now_sal from emp where empno = m_empno;

15 commit;

16 –||’平均薪水’||avgsal –加上平均薪水有问题

17 dbms_output.put_line(‘员工编号’||m_empno||’原工资’||rt_emp.sal||’现工资’||now_sal);

18 end;

–视屏

declare

myempno emp.empno%type := ‘&ha’;

empone emp%rowtype;–员工编号

avgsal number;

salone number;

–deptone dept%rowtype;–dept的行类型

begin

select * into empone from emp where empno = myempno;

–select * into deptone from dept where dept.deptno = empone.deptno;

select avg(sal)

into avgsal

from emp

group by emp.deptno

having emp.deptno=empone.deptno;

if empone.sal > avgsal then salone := empone.sal – 50;

end if;

update emp set emp.sal = salone where emp.empno = myempno;

commit;

dbms_output.put_line(‘员工编号:’ || myempno || ‘姓名:’ || empone.ename ||

‘之前工资:’ || empone.sal || ‘现在工资:’ || salone||’平均工资’||avgsal);

end;

–6.创建一个存储过程,实现:通过输入员工编号查看员工姓名,工资、奖金

–如果输入的编号不存在,进行异常处理

–如果工资高于4000,进行异常提示处理

–如果奖金没有或为0,进行异常提示处理

set serveroutput on

create or replace procedure proc(i in int) as

a varchar(20);

begin

for j in 1 .. i loop

a := a || ‘*’;

dbms_output.put_line(a);

end loop;

end;

/

set serveroutput on

exec proc(5);

create or replace procedure proc(m_empno in int)

as

rt_emp emp%rowtype;

ifexist number; –变量名写好exist 与exit

begin

select * into rt_emp from emp where emp.empno = m_empno;

select count(1) into ifexist from emp where empno = m_empno; –count(1)是emp表总行数即empno行数和

if ifexist = 0 then

dbms_output.put_line(‘您输入的编号不存在,异常’);

elsif rt_emp.sal > 4000 then

dbms_output.put_line(‘工资高于4000,异常’);

elsif rt_emp.comm is null or rt_emp.comm = 0 then

–elsif nvl(rt_emp.comm, 0) = 0 then

dbms_output.put_line(‘奖金没有或为0,异常’);

else

null;

end if;

dbms_output.put_line(‘员工编号:’ || m_empno || ‘姓名:’ || rt_emp.ename ||

‘工资:’ || rt_emp.sal || ‘奖金:’ || rt_emp.comm);

end proc;

(0)
上一篇 2022年3月22日
下一篇 2022年3月22日

相关推荐