PostgreSql 函数异常处理

BEGIN

逻辑块

EXCEPTION WHEN 错误码(如:unique_violation) or others THEN

异常逻辑块

END;

在PL/pgSQL函数中,如果没有异常捕获,函数会在发生错误时直接退出,与其相关的事物也会随之回滚。我们可以通过使用带有EXCEPTION子句的BEGIN块来捕获异常并使其从中恢复。见如下声明形式:

复制代码
[ <> ]
[ DECLARE
    declarations ]
BEGIN
    statements
EXCEPTION
  WHEN condition [ OR condition ... ] THEN
            handler_statements
  WHEN condition [ OR condition ... ] THEN
         handler_statements
END;                    

如果没有错误发生,只有BEGIN块中的statements会被正常执行,然而一旦这些语句中有任意一条发生错误,其后的语句都将被跳过,直接跳转到 EXCEPTION块的开始处。此时系统将搜索异常条件列表,寻找匹配该异常的第一个条件,如果找到匹配,则执行相应的 handler_statements,之后再执行END的下一条语句。如果没有找到匹配,该错误就会被继续向外抛出,其结果与没有EXCEPTION子 句完全等同。如果此时handler_statements中的语句发生新错误,它将不能被该EXCEPTION子句捕获,而是继续向外传播,交由其外层 的EXCEPTION子句捕获并处理。

PostgreSQL中可以利用RAISE语句报告信息和抛出错误,其声明形式为:

复制代码
RAISE level 'format' [, expression [, ...]];

这里包含的级别有DEBUG(向服务器日志写信息)、LOG(向服务器日志写信息,优先级更高)、INFO、NOTICE和WARNING(把信息写到服务器日志以及转发到客户端应用,优先级逐步升高)和EXCEPTION抛出一个错误(通常退出当前事务)。某个优先级别的信息是报告给客户端还是写到服务器日志,还是两个均有,是由log_min_messages和client_min_messages这两个系统初始化参数控制的。

在format部分中,%表示为占位符,其实际值仅在RAISE命令执行时由后面的变量替换,如果要在format中表示%自身,可以使用%%的形式表示,见如下示例:

RAISE NOTICE 'Calling cs_create_job(%)',v_job_id;--v_job_id变量的值将替换format中的%。

RAISE EXCEPTION 'Inexistent ID --> %',user_id;

简单来说:

复制代码
--抛出异常
RAISE EXCEPTION '你出问题了。该修修!'; 
--使用SQLERRM 来显示错误信息。
RAISE EXCEPTION '(%)', SQLERRM;

见如下示例:

复制代码
CREATE OR REPLACE FUNCTION GETEXCEPTION(v_phone text) RETURNS void AS
$$
BEGIN
    IF v_phone = 'iphone' THEN
       RAISE EXCEPTION '你出问题了。该修修!'; 
    ELSIF  v_phone = 'samsung' THEN  
       RAISE EXCEPTION '你会爆炸,离你远点!'; 
    else 
       RETURN;    
    END IF;
    EXCEPTION
    WHEN others THEN    
    RAISE EXCEPTION '(%)', SQLERRM; 
END
$$ LANGUAGE PLPGSQL; 
复制代码
CREATE OR REPLACE FUNCTION xx
RETURNS "public"."xx" AS $BODY$
DECLARE
err_message varchar(4000);
exception_context varchar(4000);
BEGIN
IF strDate is null then
strDate := (now()::DATE-interval '1 day');
END IF;

result.strErrorDescribe='数据录入成功'||strDate;
result.ReturnValue=0;
RETURN result;
EXCEPTION
WHEN OTHERS THEN
BEGIN
-- get stacked diagnostics exception_context=PG_EXCEPTION_CONTEXT; --获取错误的行号
--err_message := '错误行号:' || exception_context || '; 异常:' || sqlerrm;

--insert into proc_err_log values(err_message);
result.strErrorDescribe='数据异常已经回滚'; --获取异常信息
result.ReturnValue=9999;
RETURN result;
END;
END;
$BODY$
LANGUAGE plpgsql VOLATILE
COST 100
相关推荐
TimerShaft7 小时前
CentOS7安装PostgresSQL和PGVector
postgresql·centos·pgvector
2301_800256117 小时前
R-Tree创建与遍历,R-Tree在4类空间查询中的应用,实现4类空间查询的各类算法[第8章]
数据库·算法·机器学习·postgresql·r-tree
梦想画家17 小时前
实战优化:基于 pgvector 的向量存储与检索效率提升全攻略
postgresql·pgvector·语义检索
AC赳赳老秦19 小时前
Python 爬虫进阶:DeepSeek 优化反爬策略与动态数据解析逻辑
开发语言·hadoop·spring boot·爬虫·python·postgresql·deepseek
horizon72741 天前
Windows安装pgvector
postgresql·pgvector
l1t1 天前
DeepSeek辅助编写的利用唯一可选数求解数独SQL
数据库·sql·算法·postgresql
XMYX-01 天前
CentOS 7 搭建 PostgreSQL 14 实战指南
linux·postgresql·centos
a努力。1 天前
中国电网Java面试被问:分布式缓存的缓存穿透解决方案
java·开发语言·分布式·缓存·postgresql·面试·linq
Vic101011 天前
华为云高斯数据库:gsqlexec用法
java·大数据·数据库·postgresql·华为云
odoo中国2 天前
Pgpool-II 在 PostgreSQL 中的用例场景与优势
数据库·postgresql·中间件·pgpool