PostgreSQL 12 PLPGSQL函数EXCEPTION子句捕获22P02错误失效问题
问题原因分析
PL/pgSQL 函数内的 EXCEPTION 子句,仅能捕获函数体执行过程中抛出的错误,你遇到的异常捕获失效是触发时机的问题:
- 你定义的
dotest函数第一个参数为INTEGER类型,当你传入字符串'a'调用时,PostgreSQL会在调用函数前先尝试把'a'隐式转换为INTEGER类型,这个转换动作发生在函数逻辑执行之前,抛出的22P02错误自然无法被函数内部的异常捕获逻辑处理。 - 除零错误可以正常捕获,是因为除法运算执行在函数体内部,错误触发时已经处于
EXCEPTION的覆盖范围内。
解决方案
如果要实现参数类型转换错误的捕获,需要调整函数定义,把对应参数的类型放宽为可接受字符串输入的VARCHAR/TEXT类型,在函数内部手动执行类型转换,让转换错误发生在函数体内即可被捕获:
CREATE OR REPLACE FUNCTION dotest(wid VARCHAR, wname VARCHAR, wcost REAL) RETURNS INTEGER AS $$ DECLARE wdivide REAL; wid_int INTEGER; BEGIN -- 手动执行类型转换,错误将发生在函数体内可被捕获 wid_int := wid::INTEGER; wdivide := wcost / wid_int; RETURN 10; EXCEPTION WHEN sqlstate '22012' THEN -- 匹配除零错误 RETURN 1; WHEN sqlstate '22P02' THEN -- 匹配类型转换错误 RETURN 2; END; $$ LANGUAGE PLPGSQL;
调整后执行SELECT dotest('a', 'AAAAA', 12.2);就会按预期返回2。
内容的提问来源于stack exchange,提问作者Eder Domingues
相关产品推荐
相关产品推荐

