2009-06-08 15 views
6

में सिंक्रनाइज़ किए गए टेबल को रखने के लिए हम एक नए चमकदार संस्करण के साथ विरासत प्रणाली की तुलना करने के लिए साइड-बाय-साइड परीक्षण चलाने वाले हैं। हमारे पास ओरेकल डेटाबेस तालिका है, ए, जो विरासत प्रणाली के लिए डेटा संग्रहीत करता है, और समकक्ष तालिका, बी, जो नई प्रणाली के लिए डेटा संग्रहीत करता है, इसलिए परीक्षण की अवधि के लिए, डेटाबेस को denormalized है। (इसके अलावा, विरासत प्रणाली और तालिका ए निश्चित हैं - कोई बदलाव की अनुमति नहीं है)ओरेकल

मैं क्या करना चाहता हूं कि बी पर प्रसारित करने के लिए कम से कम डीएमएल संचालन को अनुमति देना है, और इसके विपरीत। मैंने ऐसा करने के लिए ट्रिगर्स की एक जोड़ी शुरू की, लेकिन स्पष्ट समस्या को मारा कि जब ट्रिगर चलते हैं, तो टेबल म्यूट कर रहे हैं, और एक अपवाद फेंक दिया जाता है।

क्या इस मुद्दे को संभालने का कोई मानक तरीका है? मैं पर किया जाए या नहीं dbms_scheduler का उपयोग कर जाने का रास्ता है भिन्न रिपोर्ट पढ़ा है ...

धन्यवाद,

एंडी

अद्यतन: मैं पूरी से बाहर chickening समाप्त कर दिया है जारी किया और सुनिश्चित किया कि ए को अद्यतन करने वाली सभी संग्रहीत प्रक्रियाएं, बी को अपडेट करें, और इसके विपरीत।

मैंने क्वास्नोई के उत्तर को स्वीकृति के रूप में चिह्नित किया है, क्योंकि अगर भविष्य में एक ही समस्या का सामना करना पड़ता है तो मैं उनके सुझावों का पालन करता हूं।

मैंने जोसेफस्टोन के जवाब को चिह्नित किया है, क्योंकि मुझे संक्षेप में टेबल ए और बी पर दो सम्मिलित/अद्यतन कथन स्तर ट्रिगर्स जोड़कर काम करना पड़ता है, फिर ए या बी को मास्टर टेबल के रूप में उपयोग करके उसकी विलय प्रक्रिया कर रही है, जिसके आधार पर ट्रिगर दौड़ गया (हालांकि पहले मैंने जांच की थी कि लक्ष्य तालिका मर्ज द्वारा बदली जाएगी, अगर नहीं तो बाहर निकलती है)।

+0

@ एंडी: यदि आपका विरासत अनुप्रयोग टेबल को अपडेट करने के लिए संग्रहीत प्रक्रियाओं का उपयोग करता है, तो भगवान के लिए केवल अपनी तर्क प्रक्रियाओं में डाल दें, क्योंकि यह बिल्कुल ठीक है। मेरी सलाह केवल खराब विकसित अनुप्रयोगों के लिए अच्छी है जो डेटा अपडेट करने के लिए डीएमएल स्टेटमेंट (प्रक्रियाओं को कॉल करने के बजाए) जारी करती हैं। – Quassnoi

उत्तर

3

मैं एक ही सामान्यीकृत (या denormalized) मेज पर विचारों के रूप में A और B बनाते हैं, और DML संचालन को संभालने के लिए इन विचारों पर एक INSTEAD OF ट्रिगर बनाया था।

क्वेरी बात की योजना बना रही है, यह टेबल की दो प्रतियां रखने के लिए बेहतर है: A_underlying और B_underlying और सिर्फ इस तरह दृश्य बना:

CREATE VIEW A 
AS 
SELECT * 
FROM A_underlying 

CREATE VIEW B 
AS 
SELECT * 
FROM B_underlying 

विधेय विचारों में धकेल दिया जाएगा, और क्वेरी की योजना वास्तविक तालिकाओं और विचारों के लिए वही होगा।

INSTEAD OF दोनों दृश्यों पर ट्रिगर्स, आपको डेटा को अंतर्निहित तालिकाओं में रखना चाहिए।

+0

जो वास्तव में एक बहुत अच्छा विचार है। दुर्भाग्य से, विरासत एप्लिकेशन और डेटाबेस स्कीमा तय कर रहे हैं। मैंने इसे प्रतिबिंबित करने के लिए प्रश्न अपडेट किया है। धन्यवाद। – Andy

+0

डेटाबेस स्कीमा बाहरी दुनिया के समान ही रहेगा। आप एक और स्कीमा में अंतर्निहित तालिकाओं को भी बना सकते हैं। ट्रिगर्स बनाकर आप अंतर्निहित तालिकाओं पर विचार बनाकर अपनी स्कीमा को कम नहीं करते हैं। – Quassnoi

+0

सच। अधिक विशिष्ट होने के लिए: मैं विरासत प्रणाली को प्रभावित किए बिना ट्रिगर्स जोड़ सकता हूं। अगर मैं एक एकीकृत टेबल एबी पर एक दृश्य बनाना चाहता था, तो मुझे दृश्य का उपयोग करने के लिए विरासत एप्लिकेशन को संशोधित करना होगा। – Andy

1

क्या आप वास्तव में डीडीएल का मतलब है, डीएमएल नहीं?

डीएमएल के साथ आप टेबल को सिंक में रखने के लिए ओरेकल Multi Master Replication पर एक नज़र डाल सकते हैं या आप इस उद्देश्य के लिए टूल SymmetricDS पर भी देख सकते हैं।

डीडीएल के साथ एकमात्र समाधान जिसे मैं जानता हूं वह फिर से Oracle advanced replication है।

+0

गाह! पाठ्यक्रम का डीएमएल - अच्छी तरह से देखा :) – Andy

1

एक संग्रहीत प्रक्रिया में तीन कथन नीचे रखो, तो यह एक अनुसूचित काम के रूप में चलाने के रूप में जितनी बार चाहें:

--Assume that "A" is a master, and "B" needs to be synched 

--If no match in "A", delete from "B" 
DELETE FROM B 
WHERE NOT EXISTS(
       SELECT * 
       FROM A 
       WHERE A.PRIMARY_KEY = B.PRIMARY_KEY 
       ); 

--If there is a match, but they are different, then update "B" 
update 
    (
    select 
    a.field1 as new_value1 
    ,b.field1 as old_value1 
    ,a.field2 as new_value2 
    ,b.field2 as old_value2 
    ,.... 
    ,a.fieldN as new_valueN 
    ,b.fieldN as old_valueN 
    from 
    a 
    ,b 
where a.primary_key = b.primary_key 
) 
set 
    old_value1 = new_value1 
,old_value2 = new_value2 
,.... 
,old_valueN = new_valueN; 


--if the record is new to "A", then insert it into "B" 
INSERT INTO B 
SELECT * 
FROM A 
WHERE NOT EXISTS(
       SELECT * 
       FROM B 
       WHERE B.PRIMARY_KEY = A.PRIMARY_KEY 
       ); 
+0

हाय जोसेफ। टेबल के बीच कोई मास्टर/गुलाम संबंध नहीं है। ए में परिवर्तन बी को प्रसारित करना चाहिए, और इसके विपरीत। मुझे लगता है कि मैं इसे प्राप्त करने के लिए अपने कोड में एक टाइमस्टैम्प जोड़ सकता हूं, क्योंकि परिवर्तन उपयोगकर्ता द्वारा शुरू किए गए हैं और समरूपता के मुद्दे असंभव हैं। धन्यवाद। – Andy

1

Oracle 10g और इसके बाद के संस्करण एक अतुल्यकालिक प्रक्रिया के रूप में परिवर्तन सूचना लागू किया है। यह स्वचालित है और पैकेज को ओरेकल 10 जी और ऊपर के सर्वर इंस्टॉल के साथ शामिल किया गया है।

आप कुछ जानकारी के लिए here देख सकते हैं।