0

I need to delete one or more row from list of tables stored in a table, and commit only if all deletion succeed. So I wrote something like this (as part of a bigger procedure):

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;

I know this couldn't work, because of the "execute immediate".

So, what is the correct way to do that?

MonkeyH
  • 13
  • 5

2 Answers2

0

Honestly, this sounds like a bad idea. Since you have the tables stored in the database, why not just list them out in your procedure? Surely, you're not adding tables that often that this procedure would need to be updated often?

As pointed out in the comments, this will work fine, since EXECUTE IMMEDIATE does not automatically commit.

Don't forget to add a RAISE at the end of your exception block, or you'll never know that an error happened.

eaolson
  • 14,717
  • 7
  • 43
  • 58
0

Dynamic SQL (Execute Immediate) doesn't commit the transaction. You have to commit explicitly. Your code is fine but it doesn't record/log the errors in case if they occur. Log the errors in the exception handler section.