Exception、Error、运行时异常与一般异常有何异同

1、Exception 和 Error 都是继承了 Throwable 类,在 Java 中只有 Throwable 类型的实例才可以被抛出(throw)或者捕获(catch),它是异常处理机制的基本组成类型。 
2、Exception 是程序正常运行中,可以预料的意外情况,可能并且应该被捕获,进行相应处理。 
3、Error 是指在正常情况下,不大可能出现的情况,绝大部分的 Error 都会导致程序(比如 JVM 自身)处于非正常的、不可恢复状态。既然是非正常情况,所以不便于也不需要捕获,常见的比如 OutOfMemoryError 之类,都是 Error 的子类。 
4、Exception 又分为可检查(checked)异常和不检查(unchecked)异常,可检查异常在源代码里必须显式地进行捕获处理,这是编译期检查的一部分。不检查异常就是所谓的运行时异常,类似 NullPointerException、ArrayIndexOutOfBoundsException 之类,通常是可以编码避免的逻辑错误,具体根据需要来判断是否需要捕获,并不会在编译期强制要求。 
5、 
常见的ERROR:NoClassDefFoundError、VirtualMachineError、OutOfMemoryError、StackOverflowError 
常见的Exception:IOException(Checked Exception) 
RuntimeException、NullPointerException、ClassCastException、SecurityException/ClassNotFoundException

6、从性能角度来审视一下 Java 的异常处理机制,这里有两个可能会相对昂贵的地方:

try-catch 代码段会产生额外的性能开销,或者换个角度说,它往往会影响 JVM 对代码进行优化,所以建议仅捕获有必要的代码段,尽量不要一个大的 try 包住整段的代码;与此同时,利用异常控制代码流程,也不是一个好主意,远比我们通常意义上的条件语句(if/else、switch)要低效。

Java 每实例化一个 Exception,都会对当时的栈进行快照,这是一个相对比较重的操作。如果发生的非常频繁,这个开销可就不能被忽略了。

注意: 
(1) 一个函数尽管抛出了多个异常,但是只有一个异常可被传播到调用端。最后被抛出的异常时唯一被调用端接收的异常,其他异常都会被吞没掩盖。 
(2) 不要在finally代码块中处理返回值。 
(3)请勿在try代码块中调用return、break或continue语句。万一无法避免,一定要确保finally的存在不会改变函数的返回值。

<think>好的,用户现在想了解PostgreSQL和Oracle存储过程的异同点,特别是语法、功能和特性方面的对比。之前用户的问题是关于Java发送复杂邮件的内容,现在突然转到了数据库存储过程,可能是在开发过程中遇到了需要迁移数据库或者多数据库支持的需求,比如从Oracle迁移到PostgreSQL,或者需要同维护两种数据库的存储过程。用户提到参考的引用内容是关于存储过程移植性的问题,这说明用户可能关心的是两者之间的兼容性,以及迁移或跨平台使用需要做的修改。 首先,我需要回顾PostgreSQL和Oracle存储过程的基本结构。Oracle使用PL/SQL,而PostgreSQL使用PL/pgSQL,两者语法上有很多相似之处,但也有不同点。比如变量声明、控制结构、异常处理等方面可能有差异。同,功能上的区别,比如事务处理、返回结果的方式、内置函数等也需要比较。 用户可能需要详细的对比,包括具体例子,这样他们在迁移或开发可以参考。比如,在语法上,变量声明Oracle是变量名在前,类型在后,而PostgreSQL可能使用DECLARE块。函数或存储过程的创建语句也不同,Oracle是CREATE OR REPLACE PROCEDURE,而PostgreSQL可能是CREATE FUNCTION加上不同的语言选项。 另外,功能特性方面,Oracle的存储过程在事务控制上可能更灵活,允许自治事务,而PostgreSQL可能需要使用特定的命令或者扩展来实现类似功能。异常处理机制两者也可能不同,比如Oracle的EXCEPTION块和PostgreSQL的EXCEPTION子句。 还需要考虑性能优化方面的差异,比如Oracle的优化器特性PostgreSQL的不同,索引类型、游标处理等。此外,高级功能如包(Oracle特有的)在PostgreSQL中如实现,或者是否有替代方案。 用户可能还想了解移植的具体步骤,常见问题及解决方案,比如如处理无法直接移植的语法,是否有工具可以辅助转换,或者最佳实践建议。 在回答,需要结构清晰,分点对比,并提供代码示例说明两者的不同,这样用户更容易理解和应用。同,根据之前的引用内容,强调移植性问题和需要修改的地方,帮助用户预见可能的挑战。最后,生成的相关问题应围绕用户可能进一步的需求,比如迁移工具、性能对比、调试方法等。</think>以下是PostgreSQLOracle存储过程在语法、功能和特性方面的详细对比分析,结合具体代码示例说明核心差异: --- ### 一、语法差异对比 #### 1. **基本结构定义** - **Oracle (PL/SQL)** ```sql CREATE OR REPLACE PROCEDURE proc_name ( p_param1 IN NUMBER, p_param2 OUT VARCHAR2 ) AS v_local_var NUMBER := 0; -- 变量声明 BEGIN -- 逻辑代码 SELECT column INTO p_param2 FROM table WHERE id = p_param1; EXCEPTION WHEN NO_DATA_FOUND THEN p_param2 := 'Not Found'; END; ``` **特点**:使用`AS`关键字开始声明部分,参数模式需明确标注`IN/OUT/IN OUT`[^2]。 - **PostgreSQL (PL/pgSQL)** ```sql CREATE OR REPLACE FUNCTION func_name ( p_param1 INTEGER, OUT p_param2 TEXT ) RETURNS TEXT AS $$ DECLARE v_local_var INTEGER := 0; -- 变量声明 BEGIN -- 逻辑代码 SELECT column INTO p_param2 FROM table WHERE id = p_param1; IF NOT FOUND THEN p_param2 := 'Not Found'; END IF; RETURN p_param2; -- 必须显式返回OUT参数 END; $$ LANGUAGE plpgsql; ``` **特点**:使用`DECLARE`块声明变量,`RETURNS`定义返回类型,需显式返回OUT参数[^3]。 #### 2. **流程控制** - **条件语句对比** ```sql -- Oracle IF condition THEN ... ELSIF condition2 THEN ... ELSE ... END IF; -- PostgreSQL IF condition THEN ... ELSIF condition2 THEN ... ELSE ... END IF; -- 语法相同 ``` - **循环语句差异** ```sql -- Oracle显式游标循环 FOR rec IN (SELECT * FROM employees) LOOP DBMS_OUTPUT.PUT_LINE(rec.emp_name); END LOOP; -- PostgreSQL隐式游标循环 FOR rec IN SELECT * FROM employees LOOP RAISE NOTICE '%', rec.emp_name; END LOOP; ``` --- ### 二、功能特性差异 #### 1. **事务控制** - **Oracle** 支持自治事务(`PRAGMA AUTONOMOUS_TRANSACTION`),允许在存储过程中提交独立事务: ```sql CREATE PROCEDURE log_error AS PRAGMA AUTONOMOUS_TRANSACTION; BEGIN INSERT INTO error_log VALUES (...); COMMIT; -- 允许显式提交 END; ``` - **PostgreSQL** **不支持存储过程内显式事务控制**(如`COMMIT/ROLLBACK`),所有操作在外部事务中执行[^4]。 #### 2. **返回结果集** - **Oracle** 使用`SYS_REFCURSOR`返回游标: ```sql PROCEDURE get_employees (p_cursor OUT SYS_REFCURSOR) AS BEGIN OPEN p_cursor FOR SELECT * FROM employees; END; ``` - **PostgreSQL** 直接通过`RETURNS SETOF`返回结果集: ```sql CREATE FUNCTION get_employees() RETURNS SETOF employees AS $$ BEGIN RETURN QUERY SELECT * FROM employees; END; $$ LANGUAGE plpgsql; ``` #### 3. **错误处理** - **Oracle** 结构化异常处理: ```sql EXCEPTION WHEN NO_DATA_FOUND THEN ... WHEN OTHERS THEN ROLLBACK; ``` - **PostgreSQL** 使用`EXCEPTION`块需配合`GET STACKED DIAGNOSTICS`: ```sql BEGIN ... EXCEPTION WHEN others THEN GET STACKED DIAGNOSTICS error_message = MESSAGE_TEXT; RAISE NOTICE 'Error: %', error_message; END; ``` --- ### 三、关键移植性问题 | 特性 | Oracle | PostgreSQL | 移植建议 | |--------------------|---------------------------------|--------------------------------|------------------------------| | **包(Package)** | 支持包(逻辑模块分组) | 无原生支持,需用Schema+函数模拟 | 拆分为独立函数 | | **集合类型** | 支持INDEX-BY表、嵌套表等 | 使用数组或JSONB替代 | 重构为数组类型 | | **动态SQL** | EXECUTE IMMEDIATE | EXECUTE ... USING | 调整参数占位符语法 | | **内置函数** | TO_CHAR(), NVL() | TO_CHAR(), COALESCE() | 替换函数名或逻辑 | --- ### 四、性能优化对比 - **Oracle优势** 支持物化视图、函数索引、并行执行(`PARALLEL`提示)。 - **PostgreSQL优势** JIT编译优化(PG11+)、扩展插件(如pg_hint_plan)、JSON处理性能更优。 --- ### 迁移实践示例 **Oracle原始代码**: ```sql CREATE PROCEDURE update_salary (emp_id IN NUMBER) AS BEGIN UPDATE employees SET salary = salary * 1.1 WHERE id = emp_id; COMMIT; -- 显式提交 EXCEPTION WHEN OTHERS THEN ROLLBACK; END; ``` **PostgreSQL移植版**: ```sql CREATE FUNCTION update_salary (emp_id INTEGER) RETURNS VOID AS $$ BEGIN UPDATE employees SET salary = salary * 1.1 WHERE id = emp_id; -- 移除非法的COMMIT语句 EXCEPTION WHEN others THEN RAISE EXCEPTION 'Update failed: %', SQLERRM; END; $$ LANGUAGE plpgsql; ``` ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值