2017-03-17 9 views
6

मैं निम्नलिखित डेटाबेस तालिकाओं है: enter image description hereअद्यतन डेटाबेस तालिकाओं

इन तालिकाओं मैं निम्नलिखित तत्व में:

  • कंटेनर: किसी भी container_item तत्व शामिल हो सकती है; संबंध तालिका का उपयोग करके संग्रहीत किया जाता है CONTAINER_CANDIDATES
  • Container_Item: कोई तत्व आइटम हो सकता है; संबंध तालिका का उपयोग करके संग्रहित किया जाता है COMPOUNDS
  • तत्व: मेरे सिस्टम में मूल तत्व।

मुझे वाक्यांश सवाल एक ठोस मामला का उपयोग कर:

तालिका तत्व मैं निम्नलिखित तत्वों स्टोर कर सकते हैं में:

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' 

तालिका कंटेनर में, मैं निम्नलिखित तत्वों को संग्रहीत कर सकता हूं:

इस तरह से मैं अपने सभी कनेक्शनों बनाई में

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

तो: तालिका CONTAINER_CANDIDATES मैं निम्नलिखित कनेक्शन बनाने का प्रयोग

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

:

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

तालिका यौगिक मैं निम्नलिखित कनेक्शन बनाने का उपयोग करना। अब सवाल यह है कि मैं कंटेनरनाम 01 और इसके तहत सभी आइटम (कंटेनर आइटम और उसके तहत तत्व) को कैसे हटा सकता हूं ताकि अन्य कंटेनर (उदाहरण: कंटेनरनाम 0) बिल्कुल प्रभावित न हो?

मैं तुम्हें जाने के लिए किया जाएगा बच्चे प्रविष्टियों एक पैरामीटर के रूप कंटेनर आईडी पारित और फिर नष्ट करने के लिए जिस तरह से एक प्रक्रिया के माध्यम से इस लक्ष्य को हासिल करना चाहते हैं एक Oracle पी एल एसक्यूएल प्रक्रिया

+0

यदि कोई सोच रहा है कि '(****) 'दबाया गया है तो दबाने वाला नहीं है। यह छद्म कोड में इस पंक्ति को इंगित करता है: '-> मौजूदा कंटेनर में केवल मौजूदा कंटेनर_इटम द्वारा उपयोग किए जाने वाले सभी तत्व प्राप्त करें (बाईं ओर स्क्रॉल करें) – 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_ITEM और ELEMENTS रखने नहीं है और हम अच्छा कर रहे हैं।

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; 
/

यह सुनिश्चित नहीं है कि आप अपनी किसी भी तालिका में अनाथ नहीं हैं।यह अधिकांश काम करने के लिए कास्केड का उपयोग करता है और दो दास तालिकाओं में अप्रयुक्त डेटा की एक छोटी सी ट्रिम करता है।

एकमात्र नकारात्मक पक्ष यह है कि यदि आप उनका उपयोग नहीं करते हैं तो यह आपको CONTAINER_ITEM और ELEMENTS में प्रवेश करने की अनुमति नहीं देगा।

+0

धन्यवाद, बहुत उपयोगी समाधान महोदय। –

+0

टिप्पणी के लिए धन्यवाद। यह वास्तव में मेरी मदद की। मैं स्पष्ट प्रक्रिया में जटिल होने का तरीका सोच रहा था। – Lucian

+0

@ लुइसियन धन्यवाद, कुछ समय के उत्तर हमें अपेक्षा से अधिक आसान होते हैं;) बीटीडब्लू, अगर आपको 'CONTAINER_ITEM' और' ELEMENTS' के थोड़ा अनाथ रखने की आवश्यकता है या केवल बड़ी टेबल पर कुछ प्रदर्शन ट्यूनिंग की आवश्यकता है, तो आप दो 'DELETE चला सकते हैं EXISTS' एक समर्पित पीआरसी में आप एक घंटे/रात/सप्ताह में एक बार दौड़ते हैं। – 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; 

जांच करें कि पहचान पत्र

+0

मैं केवल उन तत्वों और कंटेनर_इटम्स को हटाना चाहता हूं जिनका उपयोग किसी विशिष्ट कंटेनर द्वारा किया जाता है। यदि किसी तत्व/कंटेनर_इटम्स का उपयोग अन्य कंटेनर द्वारा किया जाता है तो उन्हें हटाया नहीं जाना चाहिए। मेरे पास इसके लिए एक पीएल एसक्यूएल प्रक्रिया है, लेकिन यह बहुत धीरे-धीरे काम करता है। मेरे टेबल – Lucian

+0

में मेरे पास 10 मिलियन elemnts (किसी भी तरह का) हो सकता है, इसे सुधारने के तरीके को जानने के लिए आपको अपना कोड देखना होगा। –

संबंधित मुद्दे