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:在事务中执行动态删除的主要内容,如果未能解决你的问题,请参考以下文章