PostgreSQL PL/pgSQL异常处理:如何传递column1值至audit_log表
解决PL/pgSQL异常块获取循环中column1值的问题
当然可以实现,核心思路是在存储过程的声明区定义一个变量,用来暂存循环中当前处理的column1值,让异常处理块能直接访问这个变量。
具体实现步骤
- 声明变量:在
DECLARE段定义一个与table_a.column1类型匹配的变量,用%TYPE可以自动匹配原字段类型,避免类型不兼容问题。 - 暂存当前值:循环内部每次迭代时,把当前
sq.column1的值赋值给这个变量。 - 异常块使用变量:在
EXCEPTION块中直接调用该变量,写入audit_log表。
另外,原代码存在几个语法错误需要修正:
EXCEPTION后不能加冒号,正确写法是EXCEPTION WHEN OTHERS THEN- 直接写
SELECT语句不赋值给变量会报错;插入table_c时引用b.col2、b.col3无效,需先把查询结果存入变量。
修正后的完整代码
CREATE OR REPLACE PROCEDURE SP_TEMP() LANGUAGE plpgsql AS $procedure$ declare -- 声明变量暂存当前column1值,类型与table_a.column1一致 v_current_col1 table_a.column1%TYPE; -- 声明变量存储table_b的查询结果 v_col2 table_b.col2%TYPE; v_col3 table_b.col3%TYPE; begin /* 遍历table_a的数据 */ for sq in (select a.column1, a.column2, ..., a.columnN from table_a a) loop -- 暂存当前循环的column1值 v_current_col1 := sq.column1; /* 执行其他操作(此处省略),并从table_b查询数据 */ -- 将table_b的查询结果赋值给变量 select col2, col3 into v_col2, v_col3 from table_b b where b.col1 = sq.column1; /* 插入数据到table_c */ insert into table_c values(sq.column1, sq.column2, v_col2, v_col3); end loop; EXCEPTION WHEN OTHERS THEN /* 将失败信息写入audit_log表 */ insert into audit_log(col1, stored_procedure_name, error_code) values(v_current_col1, 'SP_TEMP', SQLERRM); end $procedure$ ;
关键说明
v_current_col1变量在整个存储过程的BEGIN...END块内有效,包括异常处理段,所以异常发生时能获取到最后一次循环的column1值。- 使用
%TYPE定义变量类型,当原表字段类型变更时,无需修改存储过程的变量定义,更易维护。 - PL/pgSQL中直接执行
SELECT而不赋值的写法不符合语法,必须用INTO把查询结果存入变量才能后续使用。
内容的提问来源于stack exchange,提问作者Bobby John
相关产品推荐
相关产品推荐

