变量的定义
1.先从小例子入门:
declare
i number(2) := 10;
s varchar(10) := 'Guapi';
begin
dbms_output.put_line(i);
dbms_output.put_line(s);
end;
体会一下方法的声明,变量的定义和初始化,如何打印输出
2.直接引用某个表中的字段类型:表名.字段名%type
,为引用变量,
如
ena = emp.ename%type;
3.另外一种给变量赋值的方法:在select的时候使用into。
例子:
select ename into ena from emp where empno = 10000;
4.表中的一行为一个对象,定义变量的时候也可以定义对象类型的变量,为记录型变量,如:
emprow emp%rowtype;
5.dbms_output.put_line的连接符为||
如:
emprow emp%rowtype;
dbms_output.put_line(emprow.ename || '的工作为:' || emprow.job);
if条件判断
1.小例子
declare
i number(3) := &i;
begin
if i < 18 then
dbms_output.put_line('未成年');
elsif i <40 then
dbms_output.put_line('中年人');
else
dbms_output.put_line('老年人');
end if;
end;
--上面的&i表示输入一个值,&后面写什么都行,不一定是i,最后是赋值给i
loop循环
1.小例子:
declare
i number(2) := 1;
begin
while i<11 loop
dbms_output.put_line(i);
i := i + 1;
end loop;
end;
2.退出循环:
declare
i number(2) := 1;
begin
loop
exit when i > 10;
dbms_output.put_line(i);
i := i + 1;
end loop;
end;
3.for循环
declare
begin
for i in 1...10 loop
dbms_output.put_line(i);
end loop;
end;
游标
1.功能:可以存放多个对象,即多行记录
2.游标的使用步骤:定义游标–>打开游标–>取值–>关闭游标。
小例子:输出emp表中所有员工的姓名。
declare
cursor c1 is select * from emp;
emprow emp%rowtype;
begin
open c1;
loop
fetch c1 into emprow;
exit when c1%notfound;
dbms_output.put_line(emprow.ename);
end loop;
close c1;
end;
3.带参数的游标。
用法:在定义的时候声明参数类型并写where条件–>打开的时候赋值,关闭的时候不用。
小例子:给指定部门员工涨工资。
declare
cursor c1(eno emp.empno%type) is select empno from emp where empno = eno;
en emp.empno%type;
begin
open c1(10);
loop
fetch c1 into en;
exit when c1%notfound;
update emp set sal=sal+100 when empno=en;
commit;
end loop;
close c1;
end;
存储过程
1.小例子:给指定员工涨薪100元。
create or replace procedure p1(eno emp.empno%type)
is
begin
update emp set sal=sal+100 where empno=eno;
commit;
end;
--or replace可以省略,但最好写上,作用是如果数据库中已经存在名为p1的存储过程,那么会报错,加上就不会,表示修改
--可以先忽略is是干嘛用的
--调用存储过程:
declare
begin
p1(10000);
end;
存储函数
1.格式:
create or replace function 函数名(Name in type,Name in type,...)return 返回值类型 is或As 结果变量 数据类型;
begin
return (结果变量);
end 函数名;
2.例子:计算指定员工的年薪
create or replace function f_yearsal(eno emp.empno%type)return number is res number(10);
begin
select sal*12+nvl(comm,0) into res from emp where empno=eno;
return res;
end f_yearsal;
3.注意
(1)存储过程和存储函数的参数类型都不能带长度,如
create or replace function f_yearsal(eno number(10))
是错误的
(2)存储函数的返回值类型不能带长度,如
create or replace function f_yearsal(eno emp.empno%type)return number(10)
是错误的
(3)存储函数在调用的时候,返回值需要接收,否则调用错误
out类型参数
1.存储过程的形参默认是in类型的。
2.凡是涉及到into查询语句赋值或者:=赋值操作的参数,都必须使用out来修饰,其它情况不需要使用out来修饰。如果是属于其它情况,但是却用out来修饰了,也会出错。
3.例子
declare or replace procedure p_yearsal(eno emp.empno%type,yearsal out number) is
s number(10);
c emp.comm%type;
begin
select sal*12,nvl(comm,0) into s,c from emp where empno=eno;
yearsal := s + c;
end;
--使用该存储过程
declare
yearsal number(10);
begin
p_yearsal(10000,yearsal);
dbms_output.put_line(yearsal);
end;
触发器
1.分为语句级和行级,进行增删改时触发,查不触发。
语句级:执行完一条语句触发一次。
行级:有for each row,对每行记录触发一次。
2.触发器定义后满足条件时自动触发,不用手动调用。
3.触发器可以抛异常,异常代码在-20001到-20999之间
4.对于:old和:new
语句 :old :new
insert 所有字段都是空null 将要插入的数据
update 更新之前改行的值 更新之后的值
delete 删除之前该行的值 所有字段都是空null
5.语句级触发器例子
create or replace trigger t1
after
insert
on emp
declare
begin
dbms_output.put_line('一个新员工入职');
end;
6.行级触发器例子:
不能给员工降薪。
create or replace trigger t2
before
update
on emp
for each row
declare
begin
if :old.sal>:new.sal then
raise_application_error(-20001,'不能给员工降薪');
end if;
end;
7.使用触发器实现主键自增
--先新建一个序列,序列默认从1开始
--新建一个序列之后,必须先执行nextval,不能直接调用currval
--dual是虚表,只是为了补全语法,没有任何其它意义
create sequence s_person;
select s_person.nextval from dual;
create or replace trigger autoid
before
insert
op person
for each row
declare
begin
select s_person.nextval into :new.pid from dual;
end;