删除触发器后无法删除的回收站对象

Posted

技术标签:

【中文标题】删除触发器后无法删除的回收站对象【英文标题】:Recycle bin object that can't be removed after deleting a trigger 【发布时间】:2018-12-21 22:41:19 【问题描述】:

我使用的是 Oracle 版本 12c。我创建了一个触发器,它应该创建一个审计条目,因此它被称为before update(我简化了以下示例以使其可读 - 错误保持不变)。我将 ant 目标用于clean db(整个recreate 目标的第一步)。 clean db 步骤如下:

BEGIN
    FOR c IN (SELECT object_name FROM user_procedures) LOOP
        EXECUTE IMMEDIATE ('DROP PROCEDURE "' || c.object_name || '"');
    END LOOP;
END;
/

user_tablesuser_views 还有两个循环(为简洁起见,调用顺序是user_tables,然后是user_views,然后是user_procedures)。当我将触发器放入迁移脚本时(我正在使用 flyway):

CREATE OR REPLACE TRIGGER trg_car_audit
    BEFORE UPDATE
    ON CAR
    FOR EACH ROW
BEGIN
    INSERT INTO CAR (ID, MANUFACTURER, MODEL)
    VALUES (:OLD.ID, :OLD.MANUFACTURER, :OLD.MODEL);
END;
/

在整个recreate db ant 目标中,它到达clean db 目标中的点,我得到:

Failed to execute:  BEGIN FOR c IN (SELECT object_name FROM user_procedures) LOOP EXECUTE IMMEDIATE ('DROP PROCEDURE "' || c.object_name || '"'); END LOOP; END; 
java.sql.SQLSyntaxErrorException: ORA-04043: object BIN$fZDGeHfvC9bhUiQJFawHpg==$0 doesn't exist

当我执行:SELECT * FROM user_procedures,它给了我:

OBJECT_NAME                     PROCEDURE_NAME OBJECT_ID SUBPROGRAM_ID OVERLOAD  OBJECT_TYPE  AGGREGATE  PIPELINED  IMPLTYPEOWNER IMPLTYPENAME PARALLEL INTERFACE  DETERMINISTIC AUTHID   ORIGIN_CON_ID
------------------------------- -------------- --------- ------------- --------- ------------ ---------- ---------- ------------- ------------ -------- ---------- ------------- -------  -------------
BIN$fZDGeHfvC9bhUiQJFawHpg==$0  NULL           120236    1             NULL      TRIGGER      NO         NO         NULL          NULL         NO       NO         NO            DEFINER  0

我只能通过purge recyclebin; 摆脱它。


    bin* 条目放在 user_procedures桌子? 有办法解决吗?怎么样?

我有DROP ANY PROCEDURE 系统权限(我确实有其他程序,它们被完全删除了)

【问题讨论】:

通常为了避免 bin$ 是在删除对象时使用 purge 命令。但请注意,您可以闪回。 【参考方案1】:

您的程序试图删除已经删除的东西。您可以识别它,因为它的名称以“BIN$”开头。清除确认后问题消失。

解决方案是过滤不以'BIN$'开头的object_name

BEGIN
    FOR c IN (SELECT object_name FROM user_procedures
              WHERE object_name NOT LIKE 'BIN$%' ) LOOP
        EXECUTE IMMEDIATE ('DROP PROCEDURE "' || c.object_name || '"');
    END LOOP;
END;
/

【讨论】:

通常我会跳过这部分,因为我不想浪费帮助我的人的时间。但我为此苦苦挣扎,这很简单。很抱歉,我必须这样做:“非常感谢,先生!”

以上是关于删除触发器后无法删除的回收站对象的主要内容,如果未能解决你的问题,请参考以下文章

启用触发器时无法删除行

为什么固态硬盘删除数据后无法恢复?

快速恢复电脑删除文件

数据迁移服务 (DMS):出现错误后如何继续(无法执行删除语句)?

清空回收站删除文件却没有释放空间该怎么办?

ubuntu Linux系统无法将文件移动到回收站,只能直接删除。请问怎么解决?如下图: