दो डेटाबेस के बीच विदेशी कुंजी संबंध जोड़ें


90

मेरे पास दो अलग-अलग डेटाबेस में दो टेबल हैं। तालिका 1 में (डेटाबेस 1 में) स्तंभ 1 नामक एक कॉलम है और यह एक प्राथमिक कुंजी है। अब तालिका 2 (डेटाबेस 2 में) कॉलम 2 नामक एक कॉलम है और मैं इसे एक विदेशी कुंजी के रूप में जोड़ना चाहता हूं।

मैंने इसे जोड़ने की कोशिश की और इसने मुझे निम्न त्रुटि दी:

Msg 1763, Level 16, State 0, Line 1
क्रॉस-डेटाबेस विदेशी कुंजी संदर्भ समर्थित नहीं हैं। विदेशी कुंजी Database2.table2।

Msg 1750, Level 16, State 0, Line 1
बाधा नहीं बना सका। पिछली त्रुटियों को देखें।

मैं ऐसा कैसे करूं क्योंकि टेबल अलग-अलग डेटाबेस में हैं।

जवाबों:


84

आपको एक ट्रिगर का उपयोग करके डेटाबेस में संदर्भ योग्य बाधा को प्रबंधित करने की आवश्यकता होगी।


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

उदाहरण:

Create Trigger dbo.MyTableTrigger ON dbo.MyTable, After Insert, Update
As
Begin

   If NOT Exists(select PK from OtherDB.dbo.TableName where PK in (Select FK from inserted) BEGIN
      -- Handle the Referential Error Here
   END

END

संपादित: केवल स्पष्ट करने के लिए। यह संदर्भात्मक अखंडता को लागू करने के साथ सबसे अच्छा तरीका नहीं है। आदर्श रूप से आप दोनों तालिका एक ही db में चाहते हैं, लेकिन यदि यह संभव नहीं है। फिर उपरोक्त आपके लिए एक संभावित कार्य है।


3
@ जॉन हार्टसॉक - उपरोक्त उदाहरण आसानी से विफल हो सकता है, बिना उचित लेनदेन से जुड़े। समस्या के प्रकार की एक सभ्य चर्चा जो "यदि मौजूद नहीं है (तब सम्मिलित करें") के साथ हो सकती है, तो यहां पाया जा सकता है - stackoverflow.com/questions/108403/…
EBarr

16
@ जॉन हार्टसॉक - आपके समाधान में एक खामी है: यदि दो डेटाबेसों में से एक बैकअप से बहाल हो जाता है, तो ट्रिगर निश्चित रूप से फायर नहीं करता है। यह हम अनाथ पंक्तियों के साथ समाप्त कर सकते हैं।
AK

4
@AlexKuznetsov बिल्कुल। जैसा कि मैंने समझाया कि यह सबसे अच्छा तरीका नहीं है, बल्कि एक संभावित काम है।
जॉन हार्टसॉक

2
यह सिर्फ इतना गलत है ... मुझे उम्मीद है कि ओपी को पता चलता है कि बस इस तथ्य से कि वह कुछ इस तरह से पूछ रहा है, एक लक्षण है कि वह सबसे अधिक संभावना है कि कुछ गलत कर रहा है ... अकेले ट्रिगर के बारे में सोचने दें ..
MeTitus

1
@Marco जैसा कि मैंने अपने जवाब में पोस्ट किया "बस स्पष्ट करने के लिए। यह संदर्भात्मक अखंडता को लागू करने के साथ सबसे अच्छा तरीका नहीं है। आदर्श रूप से आप दोनों तालिका को एक ही db में चाहते हैं, लेकिन अगर यह संभव नहीं है। तो उपरोक्त एक संभावित कार्य है। आप।" मैंने समझाया कि यह शायद एक अच्छा विचार नहीं है।
जॉन हार्टसॉक

48

यदि आपको रॉक सॉलिड अखंडता की आवश्यकता है, तो एक डेटाबेस में दोनों टेबल रखें, और FK बाधा का उपयोग करें। यदि आपकी मूल तालिका किसी अन्य डेटाबेस में है, तो कोई भी किसी को भी पुराने बैकअप से उस मूल डेटाबेस को पुनर्स्थापित करने से रोकता है, और फिर आपके पास अनाथ हैं।

यही कारण है कि डेटाबेस के बीच FK समर्थित नहीं है।


27

मेरे अनुभव में, इसे संभालने का सबसे अच्छा तरीका है जब दो टेबल के लिए संबंधित आधिकारिक आधिकारिक स्रोत जो दो अलग-अलग डेटाबेस में हैं, प्राथमिक स्थान से तालिका की एक प्रति को माध्यमिक स्थान (टी का उपयोग करके) को सिंक करने के लिए है SQL या SSIS उपयुक्त त्रुटि जाँच के साथ - आप किसी तालिका को काट-छाँट नहीं कर सकते हैं, जबकि इसमें एक विदेशी कुंजी संदर्भ है, इसलिए तालिका अद्यतन करने के लिए बिल्ली को चमड़ी देने के कुछ तरीके हैं)।

फिर तालिका में दूसरे स्थान पर एक पारंपरिक एफके संबंध जोड़ें जो प्रभावी रूप से केवल पढ़ने के लिए प्रतिलिपि है।

आप कॉपी को अद्यतन रखने के लिए प्राथमिक स्थान पर ट्रिगर या अनुसूचित नौकरी का उपयोग कर सकते हैं।


1
पुन। "आप कॉपी को अपडेट रखने के लिए प्राथमिक स्थान पर नौकरी या अनुसूचित नौकरी कर सकते हैं": सब्स्क्राइबर की कॉपी के बाद से SQL सर्वर प्रतिकृति (विशेष रूप से लेनदेन बनाम विलय प्रकार) का उपयोग क्यों न करें (वह प्रतिलिपि जिसमें टेबल्स की आवश्यकता है विदेशी कुंजी बाधाओं की आवश्यकता है) केवल पढ़ने की जरूरत है)? देखें: लिंक
टॉम

@ हां, आप दूरस्थ डेटाबेस में अद्यतन तालिका की एक प्रति रखने के लिए निश्चित रूप से प्रतिकृति का उपयोग कर सकते हैं।
केड रूक्स

20

आप चेक बनाने के लिए उपयोगकर्ता परिभाषित फ़ंक्शन के साथ चेक बाधा का उपयोग कर सकते हैं। यह ट्रिगर से अधिक विश्वसनीय है। यह अक्षम किया जा सकता है और विदेशी कुंजी के रूप में ही आवश्यक है और एक डेटाबेस 2 पुनर्स्थापना के बाद पुनः जाँच की जा सकती है।

CREATE FUNCTION dbo.fn_db2_schema2_tb_A
(@column1 INT) 
RETURNS BIT
AS
BEGIN
    DECLARE @exists bit = 0
    IF EXISTS (
      SELECT TOP 1 1 FROM DB2.SCHEMA2.tb_A 
      WHERE COLUMN_KEY_1 =  @COLUMN1
    ) BEGIN 
         SET @exists = 1 
      END;
      RETURN @exists
END
GO

ALTER TABLE db1.schema1.tb_S
  ADD CONSTRAINT CHK_S_key_col1_in_db2_schema2_tb_A
    CHECK(dbo.fn_db2_schema2_tb_A(key_col1) = 1)

1
यह स्वीकृत उत्तर की तुलना में बेहतर समाधान है और आप इसे कई तालिकाओं पर भी उपयोग कर सकते हैं
Milox

3

संक्षिप्त उत्तर यह है कि SQL सर्वर (SQL 2008 के रूप में) क्रॉस डेटाबेस विदेशी कुंजी का समर्थन नहीं करता है - जैसा कि त्रुटि संदेश बताता है।

यद्यपि आपके पास घोषणात्मक संदर्भात्मक अखंडता (FK) नहीं हो सकती है, आप ट्रिगर्स का उपयोग करके समान लक्ष्य तक पहुंच सकते हैं। यह थोड़ा कम विश्वसनीय है, क्योंकि आपके द्वारा लिखे गए तर्क में कीड़े हो सकते हैं, लेकिन यह आपको वहीं मिलेगा।

SQL डॉक्स देखें http : // http://ddn.microsoft.com/en-us/library/aa258254%28v=sql.80%29.aspx

ट्रिगर अक्सर व्यावसायिक नियमों और डेटा अखंडता को लागू करने के लिए उपयोग किया जाता है। SQL सर्वर टेबल निर्माण स्टेटमेंट (अलर्ट टेबल और क्रिएट टेबल) के माध्यम से घोषणात्मक संदर्भात्मक अखंडता (DRI) प्रदान करता है; हालाँकि, DRI क्रॉस-डेटाबेस संदर्भात्मक अखंडता प्रदान नहीं करता है। संदर्भात्मक अखंडता (तालिकाओं की प्राथमिक और विदेशी कुंजियों के बीच संबंधों के बारे में नियम) को लागू करने के लिए, प्राथमिक और विदेशी कुंजी बाधाओं (प्राथमिक टैब और रचनात्मक तालिका के प्रमुख कुंजी और कीवर्ड) का उपयोग करें। यदि ट्रिगर टेबल पर बाधाएं मौजूद हैं, तो उन्हें ट्रिगर निष्पादन के INSTEAD और AFTER ट्रिगर निष्पादन से पहले जांच की जाती है। यदि बाधाओं का उल्लंघन किया जाता है, तो ट्रिगर क्रियाओं के INSTEAD को वापस ले लिया जाता है और AFTER ट्रिगर को निष्पादित नहीं किया जाता है (फीडेड)।

SQLTeam पर भी एक ठीक चर्चा है - http://www.sqlteam.com/forums/topic.asp?TOPIC_ID=31135


0

जैसा कि त्रुटि संदेश कहता है, यह sql सर्वर पर समर्थित नहीं है। ट्रिगर्स के साथ काम करने के लिए रेफरल क्षमता को सुनिश्चित करने का एकमात्र तरीका है।


1
क्या आप मुझे एक उदाहरण के साथ समझा सकते हैं
सैम
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.