postgresql 里面查询存储过程

查看存储过程

  • 涉及系统表pg_proc;
  • 查看所有的存储过程
select * from pg_proc where proname='fun_name';
其中参数proname是你写的存储的名称

以上sql可以导出当前数据库中的所有存储过程。

<think>我们正在使用PostgreSQL 9.2.4版本,该版本中存储过程是通过CREATE FUNCTION创建的。用户要求创建一个带有异常处理的存储过程。 异常处理在PL/pgSQL中是通过EXCEPTION块实现的。基本语法结构如下: BEGIN ... -- 正常执行的代码 EXCEPTION WHEN condition [OR ...] THEN ... -- 处理特定异常的代码 WHEN ... THEN ... -- 处理其他异常的代码 END; 常见的异常条件包括: - division_by_zero - unique_violation - check_violation - others (捕获所有异常) 注意:使用异常处理会增加性能开销,因此应谨慎使用。 示例需求:创建一个存储过程,向员工表插入数据,并处理可能出现的唯一键冲突(例如主键重复)或其他错误。 步骤: 1. 假设我们有一个employees表,结构如下: CREATE TABLE employees ( id SERIAL PRIMARY KEY, -- 注意:SERIAL类型会自动生成,但我们可以手动指定,如果手动指定重复则可能违反主键 name VARCHAR(50) NOT NULL, salary NUMERIC ); 2. 创建存储过程,插入一条新员工记录,如果出现唯一键冲突(例如主键重复)则更新该员工的薪水,如果出现其他错误则回滚并返回错误信息。 注意:在PostgreSQL中,如果发生唯一键冲突,我们可以捕获unique_violation异常。但是,由于id是SERIAL,通常不会重复,除非我们手动指定了id值。因此,我们假设用户可能手动指定id(比如在插入时包含了id字段)。 3. 存储过程设计: - 输入参数:员工id(可选,如果不提供则使用序列的下一个值)、姓名、薪水。 - 尝试插入,如果插入成功则结束。 - 如果插入时发生唯一键冲突(主键重复),则更新该id员工的薪水。 - 如果发生其他异常,则回滚事务(注意:在存储过程中,异常块内部已经是一个子事务,回滚的是该块内的操作)并返回错误信息。 4. 注意:在PostgreSQL中,存储过程(函数)中可以使用事务控制吗?在9.2版本中,函数内部不能使用BEGIN/COMMIT/ROLLBACK来管理事务,但是异常处理块会自动回滚该块内的错误操作,然后继续执行函数(在异常处理之后)。整个函数是在一个事务中运行的。 5. 我们使用一个示例函数,该函数尝试插入,如果发生唯一键冲突则更新,否则抛出其他异常。 创建存储过程(函数)的代码如下:</think>### 在 PostgreSQL 9.2.4 中创建带异常处理的存储过程PostgreSQL 9.2.4 中,存储过程通过 `CREATE FUNCTION` 实现,异常处理使用 `EXCEPTION` 块实现。以下是详细步骤和示例: --- #### 一、基本语法结构 ```sql CREATE OR REPLACE FUNCTION 函数名(参数) RETURNS 返回类型 AS $$ DECLARE -- 变量声明 BEGIN -- 主逻辑代码 EXCEPTION WHEN 错误类型 THEN -- 异常处理代码 WHEN OTHERS THEN -- 其他异常处理 END; $$ LANGUAGE plpgsql; ``` --- #### 二、完整示例:带异常处理的员工薪水更新 ```sql CREATE OR REPLACE FUNCTION update_salary( emp_id INT, new_salary NUMERIC ) RETURNS VOID AS $$ DECLARE current_salary NUMERIC; BEGIN -- 获取当前薪水 SELECT salary INTO current_salary FROM employees WHERE id = emp_id; -- 验证新薪水合理性 IF new_salary < current_salary * 0.8 THEN RAISE EXCEPTION 'Salary reduction exceeds 20%%' USING ERRCODE = 'P0001'; END IF; -- 更新操作 UPDATE employees SET salary = new_salary WHERE id = emp_id; RAISE NOTICE 'Salary updated successfully for employee %', emp_id; EXCEPTION WHEN NO_DATA_FOUND THEN RAISE EXCEPTION 'Employee ID % not found', emp_id; WHEN SQLSTATE 'P0001' THEN RAISE EXCEPTION 'Invalid salary update: %', SQLERRM; WHEN unique_violation THEN RAISE EXCEPTION 'Duplicate data violation'; WHEN OTHERS THEN RAISE EXCEPTION 'Unexpected error: %', SQLERRM; END; $$ LANGUAGE plpgsql; ``` --- #### 三、关键组件解析 1. **错误类型**: - `NO_DATA_FOUND`:查询无结果 - `unique_violation`:唯一约束冲突 - `check_violation`:检查约束冲突 - `SQLSTATE`:通过错误代码捕获(如 `P0001`) 2. **异常处理工具**: - `RAISE EXCEPTION`:抛出自定义错误 - `SQLERRM`:获取系统错误信息 - `RAISE NOTICE`:输出调试信息 3. **自定义错误代码**: ```sql RAISE EXCEPTION 'Message' USING ERRCODE = 'XXXXX'; ``` --- #### 四、调用示例 ```sql -- 正常调用 SELECT update_salary(1, 6000); -- 触发自定义异常 SELECT update_salary(1, 3000); -- 触发 P0001 错误 -- 处理不存在的员工 SELECT update_salary(999, 5000); -- 触发 NO_DATA_FOUND ``` --- #### 五、事务控制说明 在 PostgreSQL 存储过程中: 1. 整个函数默认在单个事务中运行 2. 异常发生时自动回滚当前块的操作 3. 使用 `BEGIN...EXCEPTION...END` 创建子事务块: ```sql BEGIN -- 可回滚的操作 EXCEPTION WHEN ... THEN ... END; ``` --- #### 六、性能优化建议 1. 避免过度使用异常处理(增加 2-3 倍开销) 2. 优先用数据验证替代异常捕获 3. 将频繁操作放在 `EXCEPTION` 块外部 4. 使用 `GET DIAGNOSTICS` 获取详细错误信息: ```sql GET DIAGNOSTICS variable = PG_EXCEPTION_DETAIL; ``` > 参考 PostgreSQL 9.2 官方文档:错误和消息处理章节[^1],事务管理章节[^2] ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值