2017-03-17 73 views
6

我有以下的數據庫表:enter image description here更新數據庫表

在這些表中,我有以下要素:

  • 容器:可以包含任何container_item元素;該關係使用表CONTAINER_CANDIDATES
  • Container_Item:可以包含任何元素項;該關係使用表COMPOUNDDS
  • 元素:我的系統中的基本元素。

讓我詞組用一個具體案例的問題:

在表元素,我可以存儲以下內容:

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' 

在表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' 

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

以這種方式創建我的所有連接

 - 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) 

所以:

Id = 1; ContainerName = 'ContainerName01'; 
Id = 2; ContainerName = 'ContainerName02'; 

使用表I化合物進行以下連接:

- 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) 

使用表CONTAINER_CANDIDATES我提出以下連接。 現在的問題是,如何刪除ContainerName01及其下的所有項目(容器項目和元素),以便其他Container(例如:ContainerName02)完全不受影響?

我想如果你想通過一個過程來實現這一目標的方式去將通過容器ID作爲參數,然後刪除該子項,以實現這一目標使用的是Oracle PL SQL程序

+0

如果有人想知道'(****)'是不是抑制性的咒語。它在僞代碼中表示這一行:' - >獲取當前容器中僅由當前container_item使用的所有元素(向左滾動) – APC

+0

不確定在「****僞代碼」中「當前容器」代碼行。 是否意味着所查找的元素可以被當前容器以外的容器物品使用? –

+1

請發佈創建表和插入語句,以便我可以更輕鬆地爲您開發一些代碼。 –

回答

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; 

現在,事情幾乎被自己的工作,一個小的存儲過程,以確保我們不會讓未使用的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; 
/

這不確定你從來沒有在你的任何表中的孤兒。它使用Cascade來完成大部分工作,只需在兩個從表中對未使用的數據進行小修改即可。

唯一的缺點是,如果您不使用它們,將不允許您在CONTAINER_ITEMELEMENTS中保持輸入。

+0

謝謝,非常有幫助的解決方案先生。 –

+0

感謝您的評論。這真的幫助了我。我正在想辦法使程序變得複雜。 – Lucian

+0

@Lucian謝謝,有時候答案比我們預期的要容易得多;)順便說一句,如果你需要保留一些「CONTAINER_ITEM」和「ELEMENTS」的孤兒,或者只需要對大表進行一些性能調整,那麼你可以運行兩個「DELETE EXISTS'在專用的Prc中每小時運行一次,每週一次。 – Blag

-1

你通過光標獲取。據我所知,您需要首先刪除CONTAINER_CANDIDATES和COMPOUNDS表中的條目。例如:

create or replace procedure delete_container(p_container_id number) is 

    -- Get all compound child etries via container ID 
    cursor c_get_compounds(cp_container_id number) is 
    select comp.id 
     from compounds comp, container_candidates cc 
    where comp.containerItemID = cc.containerItemID 
     and cc.containerID = cp_container_id; 

    -- Get all container candidate child entries via container ID 
    cursor c_get_container_candidates(cp_container_id number) is 
    select cc.id 
     from container_candidates cc 
    where cc.containerID = cp_container_id; 

begin 

    -- Fetch all compound entries 
    for r in c_get_compounds(cp_container_id => p_container_id) loop 
    -- Delete compound entries 
    delete from compounds where id = r.id; 
    end loop; 

    -- Fetch all container candidates 
    for r in c_get_container_candidates(cp_container_id => p_container_id) loop 
    -- Delete container candidates 
    delete from container_candidates where id = r.id; 
    end loop; 

    -- Delete container entry 
    delete from container where id = p_container_id; 
end delete_container; 

檢查ID是正確的代碼

+0

我想只刪除特定容器使用的元素和container_items。如果其他容器使用其中一個元素/ container_items,則不應刪除它們。我有一個適用於此的PL SQL過程,但工作非常緩慢。我可以在我的表格中使用多達10萬個元素(任何種類) – Lucian

+0

那麼需要查看您的代碼以瞭解如何改進它。 –