暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

存储过程无法捕获违反外键约束的错误

由迪 2024-02-06
222

原作者:彭冲

  • 适用范围
  • 问题概述
  • 问题复现
  • 问题原因
  • 解决方案

适用范围

截止MogDB 3.0所有版本

问题概述

存储过程中使用EXCEPTION子句捕获异常,违反外键约束的错误无法被捕获到。

问题复现

1.创建主表tab

create table tab(id int primary key,info varchar);
insert into tab values(100,'test');

2.创建外键引用表tab_fk

create table tab_fk(id int primary key,num int);

alter table tab_fk add constraint fk1 foreign key(id) references tab(id) on delete cascade deferrable initially deferred;

3.创建测试存储过程

create or replace procedure public.prc_test_get_error()
as 
begin
   --insert into  tab(id,info) values(100,'abcdef') ;
	insert into tab_fk values(200,100);
	EXCEPTION
   WHEN others then
     raise notice E'Got exception:
       SQLSTATE: %
       SQLERRM: %', SQLSTATE, SQLERRM; 
end;
/

4.测试调用

call prc_test_get_error();

5.调用结果

15:45:13 (omm@local:3020)postgres=# call prc_test_get_error();
ERROR:  insert or update on table "tab_fk" violates foreign key constraint "fk1"
DETAIL:  Key (id)=(200) is not present in table "tab".

6.期望结果
上面存储过程插入语句如果换成

insert into  tab(id,info) values(100,'abcdef') ;

违反主键约束,可以正常捕获错误如下:

15:44:51 (omm@local:3020)postgres=# call prc_test_get_error();
NOTICE:  Got exception:

        SQLSTATE: 23505

        SQLERRM: duplicate key value violates unique constraint "tab_pkey"
 prc_test_get_error 
--------------------
 
(1 row)

问题原因

插入主表是在存储过程执行SQL的时候报错的,所以可以捕获异常。

但是插入外键引用表tab_fk,plpgsql执行的时候是没有问题的。执行后通过触发器来实现的外键约束。

所以plpgsql不能捕获改异常,因为报错的时候,整个存储过程已经执行结束了。

解决方案

暂无

「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

文章被以下合辑收录

评论