Oracle pl/sql:在事务中执行动态删除

Posted

技术标签:

【中文标题】Oracle pl/sql:在事务中执行动态删除【英文标题】:Oracle pl/sql: executing dynamic delete within a transaction 【发布时间】:2018-07-27 09:39:42 【问题描述】:

我需要从存储在表中的表列表中删除一行或多行,并且只有在所有删除都成功时才提交。 所以我写了这样的东西(作为更大程序的一部分):

BEGIN
    SAVEPOINT sp;

    FOR cur_table IN (SELECT * FROM TABLE_OF_TABLES)
    LOOP
        EXECUTE IMMEDIATE 'DELETE FROM ' || cur_table.TABNAME || ' WHERE ID = :id_bind'
        USING id;
    END LOOP;
EXCEPTION
    WHEN OTHERS THEN
        ROLLBACK TO SAVEPOINT sp;
END;

我知道这是行不通的,因为“立即执行”。

那么,正确的做法是什么?

【问题讨论】:

有什么问题?你有错误,错误的结果,......? 我还没试过。我猜“立即执行”提交本身。有错吗? 它没有提交 id 似乎没有在任何地方定义。此外,像这样的匿名块无论如何都会在失败时回滚,因此您不需要保存点和异常处理程序。 立即执行不会自动提交。这是一种常见的误解,因为有时您将“立即执行”与 DDL 语句一起使用 - 但实际上确实提交的是 DDL 部分。 【参考方案1】:

动态 SQL(立即执行)不提交事务。你必须明确地提交。您的代码很好,但它不会记录/记录错误以防万一。 在异常处理程序部分记录错误。

【讨论】:

【参考方案2】:

老实说,这听起来是个坏主意。既然您将表存储在数据库中,为什么不在您的程序中列出它们呢?当然,您不会经常添加需要经常更新此过程的表吗?

正如 cmets 中所指出的,这可以正常工作,因为 EXECUTE IMMEDIATE 不会自动提交。

不要忘记在异常块的末尾添加RAISE,否则您永远不会知道发生了错误。

【讨论】:

以上是关于Oracle pl/sql:在事务中执行动态删除的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Oracle PL/SQL 中动态地从行参数中获取命名列?

PL/SQl,oracle 9i,使用sql删除重复行

如何实现测试隔离测试Oracle PL/SQL?

PL/SQLPL/SQL中动态执行SQL语句

PL/SQL开发中动态SQL的使用方法

在 ASP.NET MVC Core(C#) 中执行 Oracle 存储过程 (PL/SQL)