更新数据库表

Luc*_*ian 6 sql oracle plsql

我有以下数据库表: 在此输入图像描述

在这些表中,我有以下元素:

  • 容器:可以包含任何container_item元素; 使用表CONTAINER_CANDIDATES存储关系
  • Container_Item:可以包含任何元素项; 使用表COMPOUNDS存储关系
  • 元素:我系统中的基本元素.

让我用一个具体案例来说明问题:

在ELEMENTS表中,我可以存储以下元素:

Id = 1 ; ElementName = 'element001'
Id = 2 ; ElementName = 'element002'
Id = 3 ; ElementName = 'element003'
Id = 4 ; ElementName = 'element004'
Id = 5 ; ElementName = 'element005'
Id = 6 ; ElementName = 'element006'
Id = 7 ; ElementName = 'element007'
Run Code Online (Sandbox Code Playgroud)

在表CONTAINER_ITEM中,我可以存储以下元素:

Id = 1 ; ContainerItemName = 'item-id-aaa'
Id = 2 ; ContainerItemName = 'item-id-bbb'
Id = 3 ; ContainerItemName = 'item-id-ccc'
Id = 4 ; ContainerItemName = 'item-id-ddd'
Id = 5 ; ContainerItemName = 'item-id-eee'
Run Code Online (Sandbox Code Playgroud)

在表CONTAINER中,我可以存储以下元素:

Id = 1; ContainerName = 'ContainerName01';
Id = 2; ContainerName = 'ContainerName02';
Run Code Online (Sandbox Code Playgroud)

使用表COMPOUNDS我进行以下连接:

    - item-id-aaa  (id = 1 in Container_Item table)
        -> element001 (id = 1 in Elements table)
        -> element002 (id = 2 in Elements table)
    - item-id-bbb (id = 2 in Container_Item table)
        -> element003 (id = 3 in Elements table)
        -> element004 (id = 4 in Elements table)
    - item-id-ccc (id = 3 in Container_Item table)
        -> element005 (id = 5 in Elements table)
        -> element006 (id = 6 in Elements table)
    - item-id-ddd (id = 4 in Container_Item table)
        -> element005 (id = 5 in Elements table)
        -> element007 (id = 7 in Elemens table);
    - item-id-eee (id = 5 in Container_Item table)
        -> element-007 (id = 7 in Elemens table)
Run Code Online (Sandbox Code Playgroud)

使用表CONTAINER_CANDIDATES我进行以下连接:

        - ContainerName01 contains the following :
            -> item-id-aaa (id = 1 in Container_Item table)
            -> item-id-bbb (id = 2 in COntainer_Item table)
            -> item-id-ccc (id = 3 in COntainer_Item table)
            -> item-id-ddd (id = 4 in COntainer_Item table)
        - ContainerName02 contains the following:
            -> item-id-aaa (id = 1 in Container_Item table)
            -> item-id-eee (id = 5 in COntainer_Item table) 
Run Code Online (Sandbox Code Playgroud)

所以通过这种方式我创建了所有的连接.现在的问题是如何删除ContainerName01及其下的所有项目(其下的容器项和元素),以便其他容器(例如:ContainerName02)完全不受影响?

我想使用Oracle PL SQL过程实现此目的

Bla*_*lag 2

好吧,如果您遵循良好的做法,这并不是一个真正困难的问题。

首先,您有两个“多对多”跳转表(CONTAINER_CANDIDATES& COMPOUNDS),因为其中的孤立行完全无用,我们将DELETE CASCADE在它们上添加一个。

ALTER TABLE CONTAINER_CANDIDATES
ADD CONSTRAINT FK_CC_CONTAINER
   FOREIGN KEY (CONTAINERID)
   REFERENCES CONTAINER (ID)
   ON DELETE CASCADE;

ALTER TABLE CONTAINER_CANDIDATES
ADD CONSTRAINT FK_CC_CONTAINER_ITEM
   FOREIGN KEY (CONTAINERITEMID)
   REFERENCES CONTAINER_ITEM (ID)
   ON DELETE CASCADE;

ALTER TABLE COMPOUNDS
ADD CONSTRAINT FK_COMPOUNDS_CONTAINER_ITEM
   FOREIGN KEY (CONTAINERITEMID)
   REFERENCES CONTAINER_ITEM (ID)
   ON DELETE CASCADE;

ALTER TABLE COMPOUNDS
ADD CONSTRAINT FK_COMPOUNDS_ELEMENTS
   FOREIGN KEY (ELEMENTSID)
   REFERENCES ELEMENTS (ID)
   ON DELETE CASCADE;
Run Code Online (Sandbox Code Playgroud)

现在,事情几乎可以自己工作,一个小的存储过程可以确保我们不会保持未使用状态CONTAINER_ITEMELEMENTS并且我们很好。

CREATE OR REPLACE PROCEDURE cascaded_delete_container (
    P_CONTAINER_ID VARCHAR2
) IS
BEGIN
        -- remove the master from supplied ID
        -- cascade on CONTAINER_CANDIDATES
    DELETE FROM CONTAINER
    WHERE ID = P_CONTAINER_ID;

        -- remove CONTAINER_ITEM not used in CONTAINER_CANDIDATES
        -- cascade on COMPOUNDS
    DELETE FROM CONTAINER_ITEM
    WHERE NOT EXISTS(
        SELECT 1 
        FROM CONTAINER_CANDIDATES 
        WHERE CONTAINER_ITEM.ID = CONTAINER_CANDIDATES.CONTAINERITEMID
        );

        -- remove ELEMENTS not used in COMPOUNDS
    DELETE FROM ELEMENTS
    WHERE NOT EXISTS(
        SELECT 1 
        FROM COMPOUNDS 
        WHERE ELEMENTS.ID = COMPOUNDS.ELEMENTSID
        );

    COMMIT;

END;
/
Run Code Online (Sandbox Code Playgroud)

这不确定你的任何一张桌子上都不会有孤儿。它使用级联来完成大部分工作,只对两个从表中未使用的数据进行少量修剪。

唯一的缺点是,如果您不使用它们, CONTAINER_ITEM这将不允许您保留条目。ELEMENTS