Postgre数据库函数编写总结

最近PG数据库的项目上线完成,有一些bug导致的业务数据异常决定用函数/存储过程处理一下,下面是使用过程中主要用到的一些语法,记录下来分享给大家(重点参考语法就行,业务关系被我脱敏改的稀碎哈哈哈~)

CREATE OR REPLACE FUNCTION doFun() 
RETURNS integer AS
$$
declare 
  V_RECORD RECORD;
  V_SUCCESS_COUNT int;
  V_EFFECT_ROW_COUNT int;
  V_CUSTOMER_NO varchar;
  V_ERROR_MES1 varchar;
  V_ERROR_MES2 varchar;
  V_ERROR_MES3 varchar;
begin
	V_SUCCESS_COUNT := 0;
	for V_RECORD in (select * from emp ) loop
		begin
			--开始业务逻辑处理   逻辑判断阻断使用异常抛出中断 RAISE EXCEPTION 'XXXXX';
			update dept set status = '03',status_date = now(),update_time = now(),update_oper = 'SYSTEM' 
				where deptno = V_RECORD.deptno ;
			GET DIAGNOSTICS V_EFFECT_ROW_COUNT = ROW_COUNT;
			raise notice '序号:% - 开始执行',V_RECORD.serialno;
			--判断更新行数是否正常
			if V_EFFECT_ROW_COUNT = 1 then
		        select empno into V_CUSTOMER_NO from T_CUSTOMER
		        where CUSTOMER_NAME = V_RECORD.name and CERTTYPE = V_RECORD.idtype and CERTNO = V_RECORD.idno 
			        and GENDER = V_RECORD.sex and BIRTH_DATE = V_RECORD.birthday limit 1;
				if V_CUSTOMER_NO is null then
					raise notice '新增客户信息';
					--客户信息新增
					select nextval('No_seq') into V_CUSTOMER_NO;
					insert into customer (CUSTOMER_ID,CUST_NO,CUSTOMER_TYPE,CUSTOMER_NAME,CERTTYPE,CERTNO,GENDER,BIRTH_DATE,
				        LINKMAN,CONTACT_ADDR,OICQ,OPENID,CONTACT_TELEPHONE,CONTACT_TELEPHONE_SPARE,EMAIL,COMPANY_PROPER,COMPANY_INDUSTRY_TYPE,
				        COMPANY_ESTAB_DATE,INSERT_OPER,INSERT_TIME,UPDATE_TIME,UPDATE_OPER) 
			        values( nextval('Id_seq') , V_CUSTOMER_NO,
			        	'01',V_RECORD.Name,V_RECORD.idtype,V_RECORD.idno,V_RECORD.sex,V_RECORD.birthDay,
		        		V_RECORD.name,null,null,null,V_RECORD.phonenumber,null,null,null,null,null,'SYSTEM',now(),now(),'SYSTEM');
				else
					raise notice '更新客户信息';
					--客户信息更新
					update t_customer set contact_telephone = V_RECORD.phonenumber ,CUSTOMER_TYPE = '01' ,UPDATE_TIME=now() 
					where cust_no = V_CUSTOMER_NO;
				end if;
				--校验客户号是否为空
				if V_CUSTOMER_NO is null then 
					RAISE EXCEPTION '客户号获取或生成有误,执行终止';
				end if;
				raise notice '客户号:%',V_CUSTOMER_NO;
				update temp_deal set remark = '执行成功',dealstate ='Y' ,finishtime =now() where serialno =V_RECORD.serialno;
				V_SUCCESS_COUNT = V_SUCCESS_COUNT + 1;
			else 
				RAISE EXCEPTION '数据异常,终止处理';
			end if;
   		EXCEPTION
	    	WHEN others THEN    
    		GET STACKED DIAGNOSTICS V_ERROR_MES1 = MESSAGE_TEXT,V_ERROR_MES2 = PG_EXCEPTION_DETAIL,V_ERROR_MES3 = PG_EXCEPTION_HINT;
	    	raise notice '异常信息:% + % + %',V_ERROR_MES1 ,V_ERROR_MES2,V_ERROR_MES3;	
    		begin
	    		update temp_deal set remark = V_ERROR_MES1 ||V_ERROR_MES2||V_ERROR_MES3 , finishtime =now() where serialno =V_RECORD.serialno; 
			end;
		end;
   	end loop;
   	return V_SUCCESS_COUNT;
END
$$ LANGUAGE PLPGSQL;

能看到这里的小伙伴特意给你们准备了一些总结,请注意查收~

1、PG只有函数,它自身就可以实现Oracle的存储过程的功能

2、事务:每一个begin/end 块内部维护一个事务,如果执行出现异常,该模块的事务全部回滚。上述Demo中我在loop循环中也开启了一个begin/end作为子事务,用于每次循环的单独提交回滚。Exception中也单独开启了一个begin/end作为新的事务,用来记录错误信息。

3、异常:PG函数异常和其他的类似,采用层层包裹结构,内层抛出外层处理,最外层选择抛出会程序中断。在异常处理中可以采用DIAGNOSTICS 收集异常信息,它保存最近一次执行的情况,更多资料参考:PG函数异常变量

你可能感兴趣的:(PostgreSql,postgre,function,函数)