在次之前首先要搞清楚一个概念
存储过程和触发器,是在基础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是表名
                

















