【发布时间】:2020-12-17 14:15:20
【问题描述】:
在 PL/SQL (PL/pgSQL) 代码中遇到错误后,我比较了 Oracle 和 PostgreSQL 的默认行为。为此,我编写了一个类似的 Oracle 和 PostgreSQL 代码,如下所示。
Oracle 代码 (db<>fiddle):
CREATE TABLE table1 (col1 int);
CREATE PROCEDURE raise_error AS
BEGIN
INSERT INTO table1 VALUES (1/0);
END;
/
INSERT INTO table1 VALUES (1);
CALL raise_error();
COMMIT;
SELECT * FROM table1;
PostgreSQL 代码 (db<>fiddle):
CREATE TABLE table1 (col1 int);
CREATE PROCEDURE raise_error() AS $$
BEGIN
INSERT INTO table1 VALUES (1/0);
END;
$$ LANGUAGE plpgsql;
BEGIN TRANSACTION; -- disable auto-commit
INSERT INTO table1 VALUES (1);
CALL raise_error();
COMMIT;
SELECT * FROM table1;
注意:在 PostgreSQL 中,我另外运行 BEGIN TRANSACTION 语句来禁用自动提交,因为 Oracle 没有自动提交,我希望这两个代码是相似的。
SELECT * FROM table1 查询的结果在 Oracle 中是一行,在 PostgreSQL 中没有行。
如您所见,Oracle 和 PostgreSQL 中的类似代码给出了不同的结果。默认错误处理的这种差异的原因是什么?
【问题讨论】:
-
您是否在 Oracle 中启动了事务?在您的 PostgreSQL 示例中,您的事务失败,因此插入失败。这意味着该表仍然是空的。
-
@FrankHeikens,在 Oracle 中,事务是自动启动的。 PostgreSQL、MySQL 和 SQL Server 具有自动提交功能,但 Oracle 没有:stackoverflow.com/a/1366898/4592248
-
此 Oracle 行为取决于 dbfiddle 客户端在异常后继续,这不是大多数客户端的默认行为。在 sql*plus 中,您可以使用
WHENEVER SQLERROR CONTINUE ROLLBACK获得 Postgres 行为。
标签: oracle postgresql plsql transactions plpgsql