码迷,mamicode.com
首页 > 数据库 > 详细

oracle第三天

时间:2016-07-02 00:30:36      阅读:333      评论:0      收藏:0      [点我收藏+]

标签:

HelloWorld.sql

set serveroutput on

declare
--说明部分
begin
--程序
dbms_output.put_line(‘Hello World‘);
end;
/

if语句.sql

--判断用户输入的数字

set serveroutput on

--接收键盘输入
--num: 地址值,在该地址上,存了输入的值
accept num prompt ‘请输入一个数字‘;

declare
--定义变量保存输入的数字
--隐式转换
pnum number := #
begin

if pnum = 0 then dbms_output.put_line(‘您输入的是0‘);
elsif pnum = 1 then dbms_output.put_line(‘您输入的是1‘);
elsif pnum = 2 then dbms_output.put_line(‘您输入的是2‘);
else dbms_output.put_line(‘其他数字‘);
end if;
end;
/

带参数的光标.sql

--查询某个部门中员工的姓名

set serveroutput on

declare
--带参数的光标
cursor cemp(dno number) is select ename from emp where deptno=dno;
pename emp.ename%type;
begin
open cemp(20);
loop
fetch cemp into pename;
exit when cemp%notfound;

dbms_output.put_line(pename);

end loop;
close cemp;
end;
/

给员工涨工资.sql

--涨工资 总裁1000 经理800 其他400

set serveroutput on

declare
cursor cemp is select empno,empjob from emp;
pempno emp.empno%type;
pjob emp.empjob%type;
begin
rollback;

open cemp;
loop
--取一个员工 涨工资
fetch cemp into pempno,pjob;
exit when cemp%notfound;

--判断职位
if pjob = ‘PRESIDENT‘ then update emp set sal=sal+1000 where empno=pempno;
elsif pjob = ‘MANAGER‘ then update emp set sal=sal+800 where empno=pempno;
else update emp set sal=sal+400 where empno=pempno;
end if;

end loop;

close cemp;

--事务的隔离级别
commit;

dbms_output.put_line(‘涨工资完成‘);
end;
/

 光标

 

--使用游标查询员工姓名和工资,并打印

/*
1. 光标的属性
%isopen: 是否打开
%rowcount: 行数
%notfound: 没有记录

2. 默认允许一次打开300个光标(修改光标: 第四天 管理方案)
SQL> show parameters cursor

NAME TYPE VALUE
------------------------------------ ----------- -------
cursor_sharing string EXACT
cursor_space_for_time boolean FALSE
open_cursors integer 300
session_cached_cursors integer 20
*/

set serveroutput on

declare
--定义光标代表员工集合
cursor cemp is select ename,sal from emp;
pename emp.ename%type;
psal emp.sal%type;
begin
open cemp;

loop
--取一个员工
fetch cemp into pename,psal;

--退出条件
exit when cemp%notfound;

dbms_output.put_line(pename||‘的薪水是‘||psal);

end loop;

close cemp;
end;
/

 记录型变量

----查询并打印7839的姓名和薪水


set serveroutput on

declare
--记录型变量 代表一行
emp_rec emp%rowtype;
begin

select * into emp_rec from emp where empno=7839;

dbms_output.put_line(emp_rec.ename||‘的薪水是‘||emp_rec.sal);
end;
/

实例1

/*
实例1:统计每年入职的员工个数。

SQL语句
1. select to_char(hiredate,‘RR‘) from emp; --> 光标 --> 循环(notfound)
2. count80 number := 0;
count81 number := 0;
count82 number := 0;
count87 number := 0;
*/
set serveroutput on

declare
cursor cemp is select to_char(hiredate,‘RR‘) from emp;
phiredate varchar2(4);

--计数器
count80 number := 0;
count81 number := 0;
count82 number := 0;
count87 number := 0;
begin
open cemp;
loop
--取一个员工
fetch cemp into phiredate;
exit when cemp%notfound;

--判断年份
if phiredate = ‘80‘ then count80:=count80+1;
elsif phiredate = ‘81‘ then count81:=count81+1;
elsif phiredate = ‘82‘ then count82:=count82+1;
else count87:=count87+1;
end if;

end loop;
close cemp;

dbms_output.put_line(‘Total:‘||(count80+count81+count82+count87));
dbms_output.put_line(‘80:‘||count80);
dbms_output.put_line(‘81:‘||count81);
dbms_output.put_line(‘82:‘||count82);
dbms_output.put_line(‘87:‘||count87);
end;
/

 实例2

/*
为员工长工资。从最低工资调起每人长10%,但工资总额不能超过5万元,
请计算长工资的人数和长工资后的工资总额,并输出输出长工资人数及工资总额。

SQL语句:
1. select empno,sal from emp order by sal;-->光标 -->循环(1. > 5w 2. 涨完)
2. countEmp number := 0;
3. 长工资后的工资总额: *. select sum(sal) from emp
*. 涨后=涨前+sal*0.1 (*)

练习: 工资<5w
*/
set serveroutput on
declare
cursor cemp is select empno,sal from emp order by sal;
pempno emp.empno%type;
psal emp.sal%type;

--人数
countEmp number := 0;

--工资总额
salTotal number;
begin
--初始的工资总额
select sum(sal) into salTotal from emp;

open cemp;
loop
--第一个退出条件
exit when salTotal> 50000;

--取一个员工
fetch cemp into pempno,psal;

--第二个退出条件
exit when cemp%notfound;

--涨工资
update emp set sal =sal *1.1 where empno=pempno;

--人数
countEmp := countEmp+1;


--工资总额
salTotal := salTotal + psal *0.1;
end loop;
close cemp;

commit;

dbms_output.put_line(‘人数:‘||countEmp||‘ 工资总额:‘||salTotal);

end;
/

 

实例3

 

/*
用PL/SQL语言编写一程序,实现按部门分段(6000以上、(6000,3000)、3000元以下)
统计各工资段的职工人数、以及各部门的工资总额(工资总额中不包括奖金)

SQL语句
1. 部门: select deptno from dept; --> 光标 --> 循环
2. 部门中员工的薪水: select sal from emp where deptno=??? --> 带参数的光标 --> 循环
3. count1 number; count2 number; count3 number;
4. 部门工资总额: salTotal number;
select sum(sal) into salTotal from emp where deptno=???
*/
set serveroutput on

declare
--部门
cursor cdept is select deptno from dept;
pdeptno dept.deptno%type;

--部门中员工的薪水
cursor cemp(dno number) is select sal from emp where deptno=dno;
psal emp.sal%type;

--计数器
count1 number; count2 number; count3 number;

--部门的工资总额
salTotal number;
begin
open cdept;
loop
--取一个部门
fetch cdept into pdeptno;
exit when cdept%notfound;

--初始化
count1:=0;count2:=0;count3:=0;

--部门的工资总额
select sum(sal) into salTotal from emp where deptno=pdeptno;

--部门中员工的薪水
open cemp(pdeptno);
loop
--取一个员工的薪水cl
fetch cemp into psal;
exit when cemp%notfound;

--判断
if psal< 3000 then count1:=count1+1;
elsif psal>=3000 and psal<6000 then count2:=count2+1;
else count3:=count3+1;
end if;

end loop;
close cemp;

-- 保存当前结果
insert into msg1 values(pdeptno,count1,count2,count3,nvl(salTotal,0));

end loop;
close cdept;

commit;

dbms_output.put_line(‘完成‘);
end;
/

系统例外

--被0除

set serveroutput on

declare
pnum number;
begin
pnum := 1/0;

exception
when Zero_Divide then dbms_output.put_line(‘1:0不能做被除数‘);
dbms_output.put_line(‘2:0不能做被除数‘);
when Value_error then dbms_output.put_line(‘算术或转换错误‘);
when others then dbms_output.put_line(‘其他例外‘);
end;
/

--打印1~10

set serveroutput on

declare
pnum number := 1;
begin
loop
--退出循环
exit when pnum > 10;

dbms_output.put_line(pnum);

--加一
pnum := pnum + 1;

end loop;
end;
/

引用型变量

--查询并打印7839的姓名和薪水

set serveroutput on

declare
--定义引用型变量
pename emp.ename%type;
psal emp.sal%type;
begin

--查询7839的姓名和薪水
select ename,sal into pename,psal from emp where empno=7839;

-- 打印
dbms_output.put_line(pename||‘的薪水是‘||psal);
end;
/

自定义例外

--查询50号部门的员工

set serveroutput on

declare
cursor cemp is select ename from emp where deptno=50;
pename emp.ename%type;

--自定义例外
no_emp_found exception;
begin
open cemp;

--取一个员工
fetch cemp into pename;

if cemp%notfound then
--抛出例外
raise no_emp_found;
end if;

--当抛出例外,自动关闭
close cemp;

exception
when no_emp_found then dbms_output.put_line(‘没有找到员工‘);
when others then dbms_output.put_line(‘其他例外‘);
end;
/

out参数

/*
create [or replace] PROCEDURE 过程名(参数列表)
AS
PLSQL子程序体;
查询并返回某个员工的姓名 月薪和职位

思考: out参数太多???
*/
create or replace procedure queryEmpInfo(eno in number,
pename out varchar2,
psal out number,
pjob out varchar2)
as
begin
select ename,sal,empjob into pename,psal,pjob from emp where empno=eno;

end;
/

触发器应用场景二

/*
数据确认

涨后的薪水不能少于涨前的薪水
CREATE [or REPLACE] TRIGGER 触发器名
{BEFORE | AFTER}
{DELETE | INSERT | UPDATE [OF 列名]}
ON 表名
[FOR EACH ROW [WHEN(条件) ] ]
PLSQL 块

*/
create or replace trigger checksal
before update
on emp
for each row
begin
--if 涨后的薪水< 涨前的薪水 then
if :new.sal < :old.sal then
raise_application_error(-20002,‘涨后的薪水不能少于涨前的薪水.涨前:‘||:old.sal||‘ 涨后:‘||:new.sal);
end if;
end;
/

触发器应用场景一

/*
实施复杂的安全性检查

禁止在非工作时间 往emp表中插入数据
CREATE [or REPLACE] TRIGGER 触发器名
{BEFORE | AFTER}
{DELETE | INSERT | UPDATE [OF 列名]}
ON 表名
PLSQL 块

周末:to_char(sysdate,‘day‘) in (‘星期六‘,‘星期日‘)
上班前 下班后: to_number(to_char(sysdate,‘hh24‘)) not between 9 and 18
*/
create or replace trigger securityEmp
before insert
on emp
begin
if to_char(sysdate,‘day‘) in (‘星期六‘,‘星期日‘) or
to_number(to_char(sysdate,‘hh24‘)) not between 9 and 18 then

raise_application_error(-20001,‘不能在非工作时间插入数据‘);

end if;
end;
/

存储函数

/*
CREATE [OR REPLACE] FUNCTION 函数名(参数列表)
RETURN 函数值类型
AS
PLSQL子程序体;

查询某个员工的年收入

*/
create or replace function queryEmpIncome(eno in number)
return number
as
psal emp.sal%type;
pcomm emp.comm%type;
begin

select sal,comm into psal,pcomm from emp where empno=eno;

return psal*12+nvl(pcomm,0);
end;
/

带参数的存储过程

/*
create [or replace] PROCEDURE 过程名(参数列表)
AS
PLSQL子程序体;

为指定的员工涨100块钱 并打印涨前和涨后的薪水
*/
create or replace procedure raiseSalary(eno in number)
as
psal emp.sal%type;
begin
--涨前薪水
select sal into psal from emp where empno=eno;

--涨100
update emp set sal=sal+100 where empno=eno;

--要不要commit???

dbms_output.put_line(‘涨前:‘||psal||‘ 涨后:‘||(psal+100));

end;
/

第一个触发器

/*
成功插入员工后,自动输出“成功插入一个新员工”
CREATE [or REPLACE] TRIGGER 触发器名
{BEFORE | AFTER}
{DELETE | INSERT | UPDATE [OF 列名]}
ON 表名
PLSQL 块

*/
create or replace trigger sayNewEmp
after insert
on emp
begin
dbms_output.put_line(‘成功插入一个新员工‘);
end;
/

第一个存储过程

/*
create [or replace] PROCEDURE 过程名(参数列表)
AS
PLSQL子程序体;

打印Hello World

调用存储过程
1. exec sayHelloWorld();
2. begin
sayHelloWorld();
sayHelloWorld();
end;
/
*/

create or replace procedure sayHelloWorld
as
--说明部分
begin
dbms_output.put_line(‘Hello World‘);

end;
/

 

oracle第三天

标签:

原文地址:http://www.cnblogs.com/zszitman/p/5634589.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!