在次之前首先要搞清楚一个概念
存储过程和触发器,是在基础sql语句之后的另一门语言,类似小学的加减乘除和奥数的关系,他们虽然都是数学,但是运算复杂度和定向思维都有了很大程度的不同
这篇文章不打算把存储过程和触发器事无巨细的讲明白,只能用简单的解释来让大家了解一个大概
他多了if、for、case、when、loop、while 等语法,在普通的sql查询里面是用不了的
%在字符串里表示后面跟上的值
比如raise notice "num为:%",num
- if
begin
if 2 > 3 then
raise notice '2大于3';
else
if 2 = 3 then
raise notice '2等于3';
else
raise notice '2小于3';
end if;
end if;
end;
- case
i int := 100;
begin
case
when i between 1 and 10 then
raise notice '[1-10]';
when i between 11 and 20 then
raise notice '[11=20]';
else
raise notice '其他值';
end case;
end;
- loop
i int := 1;
begin
loop
exit when i = 5; ---当i为5的时候退出循环
i :=i+1;
continue when mod(i,2)=0; ---continue作用,为偶数时不往下执行
raise notice '第%次执行',i;
end loop;
end;
- for
for i in 1..10 loop
// for i in reverse 10..1 ---倒序
raise notice '第%次循环!',i;
end loop;
- 游标,作用与储存,指向这个数据,然后当做一个对象来用
游标的大致用法:
declare
emp record; ---record PLsql里的类型,要储存查询出来的数据可以用它
emp_cur cursor for select * from table limit 10; ---查询前十条数据,游标指向这十条数据
engin
open emp_cur; ---打开游标
loop
fetch emp_cur into emp; ----fetch获取游标,把数据放到emp
exit when not found; ----找不到数据之后退出
raise notice '姓名:%,性别:%',emp.name,emp.sex;
end loop;
close emp_cur; ---释放游标
end;
存储过程
这个不是一个思维,而是一个行动监听
比如我写了一个存储过程,里面的有一个条件是,表格内有什么存储改动,我就做什么行动,不懂没关系,下面有例子
这是我们要用到的表
基本的表格创建,已经有sql基础的不难看懂,就不啰嗦了
首先是存储过程的语法
create or replace procedure track_change()
AS $$
declare
//这里用来声明下面会用到的变量
begin
//这里写内容
END
$$ LANGUAGE plpgsql;
//运行该存储过程
call track_change();
- 直接举栗子
查出mescsnused表里createdate在1小时之内的数据,对每一条数据by csn,usn判断在sfccsnused是否存在,不存在则输出信息:csn:xxx usn:xxx不存在,存在则检查两个表里的reusedable栏位的值是否一致,一致则输出信息:ok,否则输出:csn:xxx usn:xxx reusedable不一致。
create or replace procedure track_change1()
AS $$
declare
emp record;
emp_cur cursor for select * from mescsnused where createdate>now()-interval '1' hour;
with_count integer;
with_count1 integer;
functionname text;
errormessage text;
begin
open emp_cur;
loop
fetch emp_cur into emp;
exit when not found;
select count(*) into with_count from sfccsnused where csn=emp.csn and usn=emp.usn;
select count(*) into with_count1 from sfccsnused
where csn=emp.csn and usn=emp.usn and reusedable=emp.reusedable;
if with_count1 = 1 then
raise notice 'csn:%,usn:%,ok',emp.csn,emp.usn;
else
if with_count = 1 then
functionname := 'track_change1';
errormessage := 'csn:%,usn:%:reusedable不一致',emp.csn,emp.usn;
raise notice 'csn:%,usn:%:reusedable不一致',emp.csn,emp.usn;
else
functionname := 'track_change1';
errormessage := 'csn:%,usn:%不存在',emp.csn,emp.usn;
raise notice 'csn:%,usn:%不存在',emp.csn,emp.usn;
end if;
end if;
end loop;
close emp_cur;
END
$$ LANGUAGE plpgsql;
触发器
顾名思义,就是在你做出某一步操作时,触发这串代码,比如用来捕获异常报错等,创建一个error_log表格专门用来存放被触发后的信息,或者创建其他表格来存放旧的记录
- 触发器例子:
对mescsnused表建触发器,增删改操时触发,将异动同步到sfcscsnused,同时将csn,usn记录到datalog表,optype根据操作确定,增加:N,修改:U,删除:D,trndate用当前时间
create or replace function trg_mesc()
returns trigger
AS $$
begin
if TG_OP = 'INSERT' then
insert into public.sfccsnused(csn,usn,reusedable,createdate)
values (new.csn,new.usn,new.reusedable,CURRENT_TIMESTAMP);
insert into public.datalog (csn,usn,optype,createdate)
values (new.csn,new.usn,'N',CURRENT_TIMESTAMP);
elseif TG_OP = 'UPDATE' then
insert into public.sfccsnused(csn,usn,reusedable,createdate)
values (new.csn,new.usn,new.reusedable,CURRENT_TIMESTAMP);
insert into public.datalog (csn,usn,optype,createdate)
values (new.csn,new.usn,'U',CURRENT_TIMESTAMP);
ELSE
delete from public.sfccsnused where csn = old.csn;
insert into public.datalog (csn,usn,optype,createdate)
values (old.csn,old.usn,'D',CURRENT_TIMESTAMP);
end if;
return new;
end $$
language plpgsql;
与存储过程不同的是,写完触发器之后需要绑定表明
//trg_mesc_change 为触发器的关键字,任意取名,有意义即可
create trigger trg_mesc_change after ---before之前 after之后
insert or update or delete --在这三种操作之前记录
on mescsnused for each row --mescsnused是表名
execute function trg_mesc(); --然后执行
删除触发器绑定
DROP TRIGGER trg_mesc_change ----trg_mesc_change是触发器名
ON mescsnused; ----mescsnused是表名