Oracle - 在删除其他表中的几行之前检查行是不是存在

Posted

技术标签:

【中文标题】Oracle - 在删除其他表中的几行之前检查行是不是存在【英文标题】:Oracle - Check if row exists before deleting several rows in other tablesOracle - 在删除其他表中的几行之前检查行是否存在 【发布时间】:2021-11-11 07:21:28 【问题描述】:

如果主表的 ID 已经存在,我想删除 Oracle 数据库中的几行: 在根据其他表中的 ID 删除行之前,我尝试先进行 SELECT 以检查主表中是否存在该 ID:

DECLARE
    PROJECT_ID PLS_INTEGER;
    PROJECT_ID_TO_DELETE PLS_INTEGER;
BEGIN
    PROJECT_ID := PROJECTS_SEQ.nextval; 
    SELECT PROJ_ID INTO PROJECT_ID_TO_DELETE FROM PROJECTS WHERE PROJ_NAME_EN LIKE 'FD Project - CSB - A.1 - CFT - Final Reject of an Increase Movement - Seb';    
    IF PROJECT_ID_TO_DELETE IS NULL THEN
        DELETE FROM PROJECTS_ORG WHERE PROJ_ID = PROJECT_ID_TO_DELETE;
        DELETE FROM PROJECTS WHERE PROJ_ID  = PROJECT_ID_TO_DELETE;
        DELETE FROM MVT_ONGOING WHERE MVT_ONGOING_PROJ_ID  = PROJECT_ID_TO_DELETE;
        DELETE FROM MVT_HISTORY WHERE MVT_HISTORY_PROJ_ID  = PROJECT_ID_TO_DELETE;
    END IF;
    Insert into PROJECTS (PROJ_ID, ...) values (PROJECT_ID, ...);
    Insert into PROJECTS_ORG (PROJ_ID, ...) values (PROJECT_ID, ...);
    Insert into MVT_ONGOING (MVT_ONGOING_PROJ_ID, ...);
    Insert into MVT_HISTORY (PROJ_ID, ...) values (PROJECT_ID, ...);
END;

我收到“未找到数据”错误

您能帮我找到最佳优化解决方案吗?

谢谢

【问题讨论】:

【参考方案1】:

类似这样的:

DECLARE
   project_id_new        PLS_INTEGER;
   project_id_to_delete  PLS_INTEGER;
BEGIN
   BEGIN
      SELECT proj_id
        INTO project_id_to_delete
        FROM projects
       WHERE proj_name_en LIKE 'blabla';

      DELETE FROM projects_org WHERE proj_id = project_id_to_delete;
      DELETE FROM projects     WHERE proj_id = project_id_to_delete;
      DELETE FROM mvt_ongoing  WHERE mvt_ongoing_proj_id = project_id_to_delete;
      DELETE FROM mvt_history  WHERE mvt_history_proj_id = project_id_to_delete;
   EXCEPTION
      WHEN NO_DATA_FOUND
      THEN
         NULL;
   END;

   project_id_new := seq.nextval;
   
   INSERT INTO projects (project_id)     VALUES (project_id_new);
   INSERT INTO projects_org (project_id) VALUES (project_id_new);
END;

它有什么作用?

试图找到PROJ_ID 如果找到,执行DELETEs 你不必使用IF;如果它被发现,它是已知的。如果未找到,则引发异常 否则,NO_DATA_FOUND 将引发异常并处理 我选择了什么都不做,你可能想做点别的事情

在插入时(正如您评论的那样,您总是希望这样做):将删除部分包含在其自己的 BEGIN-EXCEPTION-END 块中,以便处理可能的 no_data_found 错误。然后,找到project_id_new 值(例如,使用序列)并在INSERT 语句中使用它。

【讨论】:

谢谢。事实上,当我尝试使用 IF 时,我在 IF 命令之后完成了几个附加命令(INSERT)。现在我不知道如何继续,因为 INSERT 命令也在 BEGIN 中。我每次都需要 INSERT 命令。您能告诉我该怎么做,因为我不知道如何放置 INSERT 吗? 我为我想要的查询编辑上面的主题 INSERT 低于 DELETE(请参阅我编辑的代码)。但是,您必须在 PROJECT_ID 中获取一些值,否则它将为 NULL。说您必须“每次”执行 INSERT,是否意味着无论 SELECT 是否返回任何内容,您都会 INSERT 吗? 我试过了,但似乎插入命令没有被执行,因为选择选择返回没有结果,并且在异常中没有任何结果。实际上,目标是仅当该项目在插入之前已经存在时才删除,以避免有 2 个具有相同标签的条目 请重新阅读我的全部答案(包括代码)。

以上是关于Oracle - 在删除其他表中的几行之前检查行是不是存在的主要内容,如果未能解决你的问题,请参考以下文章

无法删除或截断 oracle 中的表

PLSQL: BEFORE INSERT TRIGGER(在允许插入之前检查其他表中的列中的值)

oracle IMPDP导入的时候,能自动把之前表中的数据都删除吗?

oracle IMPDP导入的时候,能自动把之前表中的数据都删除吗?

Oracle 触发器检查一个表中的课程持续时间,如果课程是特定日期,则阻止更新

替换 PL/SQL 中的几行正则表达式函数