存储过程和存储函数:
指存储在数据库中供所有用户程序调用的子程序叫存储过程、存储函数。
创建存储过程
用CREATE PROCEDURE命令建立存储过程和存储函数。
语法:
create [or replace] PROCEDURE 过程名(参数列表)
AS
PLSQL子程序体;
存储函数
函数(Function)为一命名的存储程序,可带参数,并返回一计算值。函数和过程的结构类似,但必须有一个RETURN子句,用于返回函数值。函数说明要指定函数名、结果值的类型,以及参数类型等。
建立存储函数的语法:
CREATE [OR REPLACE] FUNCTION 函数名(参数列表)
RETURN 函数值类型
AS
PLSQL子程序体;
一般来讲,过程和函数的区别在于函数可以有一个返回值;而过程没有返回值。
但过程和函数都可以通过out指定一个或多个输出参数。我们可以利用out参数,在过程和函数中实现返回多个值。
如果只有一个返回值,用存储函数;否则,就用存储过程。
打印Hello World
create or replace procedure sayHelloWorld
as
--说明部分
begin
dbms_output.put_line('Hello World');
end;
/
调用存储过程
exec sayHelloWorld();
begin
sayHelloWorld();
sayHelloWorld();
sayHelloWorld();
end;
/
--带参数的存储过程 给指定的员工涨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 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;
/
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;
/
触发器
数据库触发器是一个与表相关联的、存储的PL/SQL程序。每当一个特定的数据操作语句(Insert,update,delete)在指定的表上发出时,Oracle自动地执行触发器中定义的语句序列。
触发器的类型
语句级触发器
在指定的操作语句操作之前或之后执行一次,不管这条语句影响了多少行 。
行级触发器(FOR EACH ROW)
触发语句作用的每一条记录都被触发。在行级触发器中使用old和new伪记录变量, 识别值的状态。
CREATE [or REPLACE] TRIGGER 触发器名
{BEFORE | AFTER}
{DELETE | INSERT | UPDATE [OF 列名]}
ON 表名
[FOR EACH ROW [WHEN(条件) ] ]
PLSQL 块
触发器可用于
数据确认
实施复杂的安全性检查
做审计,跟踪表上所做的数据操作等
数据的备份和同步
--当成功插入一个新员工后,自动打印“成功插入一个新员工
create or replace trigger sayNewEmp
after insert
on emp
begin
dbms_output.put_line('成功插入一个新员工');
end;
/
--禁止在非工作时间插入员工
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 trigger checksal
before update
on emp
for each row
begin
--if 涨前的薪水 > 涨后的薪水 then
if :old.sal > :new.sal then
raise_application_error(-20002,'涨后的薪水不能少于涨前的薪水.涨前:'||:old.sal||' 涨后:'||:new.sal);
end if;
end;
/
查询触发器、过程及函数
Select * from user_triggers;
Select * from user_source;
原创文章,作者:Maggie-Hunter,如若转载,请注明出处:https://blog.ytso.com/4236.html