क्या मेरे पास SQL ​​सर्वर में एक दृश्य में एक कॉलम को संदर्भित करने वाली एक विदेशी कुंजी हो सकती है?


84

SQL Server 2008 में और दिया गया

TableA(A_ID, A_Data)
TableB(B_ID, B_Data)
ViewC(A_or_B_ID, A_or_B_Data)

क्या यह परिभाषित करना संभव है TableZ(A_or_B_ID, Z_Data)कि Z.A_or_B_IDस्तंभ उन मूल्यों के लिए विवश है, जिनमें पाया गया है ViewC? क्या यह देखने के खिलाफ एक विदेशी कुंजी के साथ किया जा सकता है?

जवाबों:


108

आप किसी विदेशी कुंजी में दृश्य नहीं देख सकते।


37
यह SQL सर्वर की एक सीमा है या यह एक अनुचित बात करना चाहता है?
आरोन एनोडाइड

1
@ ब्रायन मुझे यह जानने में भी दिलचस्पी होगी कि क्या यह SQL सर्वर की एक सीमा है या एक अनुचित चीज है क्योंकि मैं इस बिंदु पर केवल FK समर्थन प्राप्त करने के लिए ट्रिगर का उपयोग करके एक दृश्य का अनुकरण करने वाला हूं (हालांकि मैं MySql का उपयोग कर रहा हूं )।
स्लेज

4
यह इन अनुवर्ती प्रश्नों का एक अच्छा जवाब है - stackoverflow.com/questions/3833150/…
क्रिस हैल्को

मुझे यकीन नहीं है कि उन सवालों का कितना अच्छा जवाब है ... यह एक अलग DBMS के बारे में है और कहते हैं कि विचार स्कीमा विवरण और उपयोगकर्ता सुविधा को छिपाने के लिए डिज़ाइन किए गए थे। सबसे पहले, ठीक है ... लेकिन यह शुरुआती डिजाइन से परे ठोस उपयोग के मामलों को खोजने वाली पहली चीज नहीं होगी। दूसरे, मुझे यकीन नहीं है कि एक एफके ऐसा क्यों नहीं करेगा। एक दृश्य किसी भी प्रश्न हो सकता है यह भी एक मेज से बाहर खींचने के लिए नहीं है, यह एक साथ संघटित स्थिरांक का एक गुच्छा हो सकता है ... एक विदेशी कुंजी उस मामले में बहुत समझदार लगता है। अगर कोई कारण है तो मैं कुछ गहरी करने की उम्मीद नहीं करूंगा।
जॉर्ज मौयर

27

पुराने SQL सर्वर संस्करणों में ट्रिगर के माध्यम से ही विदेशी कुंजी संभव थी। आप एक आवेषण ट्रिगर बनाकर एक कस्टम विदेशी कुंजी की नकल कर सकते हैं जो यह जांचता है कि सम्मिलित मूल्य प्रासंगिक तालिकाओं में से एक में भी प्रकट होता है या नहीं।


3
StackOverflow में आपका स्वागत है। मुझे आपके उत्तर में मूल्य मिला क्योंकि वर्कअराउंड प्रदान करता है, लेकिन सही उत्तर स्वीकार किया जाता है, और यह प्रश्न 4 साल से अधिक पुराना है, इसलिए मैं सिर्फ वोट नहीं कर रहा हूं, लेकिन इस टिप्पणी के बिना छोड़ना नहीं चाहता।
जचुगेट

16

यदि आपको वास्तव A_or_B_IDमें TableZ की आवश्यकता है, तो आपके पास दो समान विकल्प हैं:

1) नल जोड़े A_IDऔर B_IDतालिका z करने के लिए कॉलम, बनाने के A_or_B_IDइन दो स्तंभों पर IsNull का उपयोग कर एक अभिकलन स्तंभ है, और एक जांच बाधा जोड़ने ऐसी है कि केवल एक काA_ID या B_IDअशक्त नहीं है

2) टेबल जेड में एक टेबलनाम कॉलम जोड़ें, जिसमें ए या बी शामिल करने के लिए विवश हैं। अब बनाएं A_IDऔरB_ID गणना किए गए कॉलम के रूप में, जो केवल गैर-अशक्त होते हैं जब उनकी उपयुक्त तालिका का नाम (CASE अभिव्यक्ति का उपयोग करके) होता है। उन्हें भी कायम रखें

दोनों ही मामलों में, आपके पास अब A_IDऔर B_IDकॉलम हैं जो बेस टेबल के लिए उपयुक्त विदेशी कुंजी हो सकते हैं। अंतर वह है जिसमें कॉलम की गणना की जाती है। इसके अलावा, यदि आपको 2 ID कॉलम के डोमेन ओवरलैप नहीं होते हैं, तो ऊपर दिए गए विकल्प 2 में TableName की आवश्यकता नहीं है - जब तक कि आपकी स्थिति अभिव्यक्ति यह निर्धारित कर सकती है कि कौन सा डोमेन किस क्षेत्र में A_or_B_ID आता है

(मेरे प्रारूपण को ठीक करने के लिए टिप्पणी के लिए धन्यवाद)


बैक-टिक्स में अंडरस्कोर के साथ शब्द डालें: A_or_B_ID
बिल कार्विन

मैं एक विरासत प्रणाली में कुछ सुविधाओं को जोड़ने पर काम कर रहा हूं, और यह पुराने और नए को एक साथ पैच करने का एक शानदार तरीका है। धन्यवाद!
डेविड गुंडरसन


4

एक और विकल्प है। TablePrime नामक एक नई तालिका के उपवर्गों के रूप में TableA और TableB को समझो। टेबलबी के आईडी मूल्यों को समायोजित करें ताकि वे टेबलए के आईडी मूल्यों के साथ मेल न खाएं। TablePrime पीके में आईडी बनाएं और TableAr में TableA और TableB's (समायोजित) आईडी के सभी डालें। TablePrime में एक ही आईडी के लिए उनके पीके पर TableA और TableB के संबंध बनाएं।

अब आपके पास सुपरटाइप / उपप्रकार पैटर्न है, और टेबलप्रेम (जब आप या तो ए-या-बी चाहते हैं ) या व्यक्तिगत तालिकाओं में से एक (जब आप केवल ए या केवल बी चाहते हैं तो अड़चन बना सकते हैं )

यदि आपको अधिक विवरण चाहिए तो कृपया पूछें। ऐसी विविधताएं हैं जो आपको यह सुनिश्चित करने देंगी कि ए और बी पारस्परिक रूप से अनन्य हैं, या हो सकता है कि आप जिस चीज के साथ काम कर रहे हैं वह एक ही समय में दोनों हो। यदि संभव हो तो एफके में औपचारिक रूप से यह सबसे अच्छा है।


2

एक बाधा को जोड़ना आसान है जो एक उपयोगकर्ता परिभाषित फ़ंक्शन का संदर्भ देता है जो आपके लिए चेक बनाता है, fCheckIfValueExists (columnValue) जो कि सही है अगर मान मौजूद है और गलत है यदि यह नहीं है।

उल्टा यह है कि यह कई कॉलम प्राप्त कर सकता है, उनके साथ गणना कर सकता है, नल को स्वीकार कर सकता है और उन मूल्यों को स्वीकार कर सकता है जो प्राथमिक कुंजी के अनुरूप नहीं हैं या जॉइन के परिणामों की तुलना नहीं करते हैं।

नकारात्मक पक्ष यह है कि आशावादी अपने सभी विदेशी कुंजी चालों का उपयोग नहीं कर सकता है।


1
नकारात्मक पक्ष यह है कि आशावादी अपने सभी विदेशी कुंजी चालों का उपयोग नहीं कर सकता है ... और यह कि फ़ंक्शन आपके द्वारा डाली जाने वाली प्रत्येक पंक्ति के लिए चलाया जाएगा / अपडेट किया जाएगा (इसलिए सेट के लिए बहुत अच्छा नहीं)।
jimbobmcgee

1

क्षमा करें, शब्द के सख्त अर्थ में, नहीं, आप विचारों पर विदेशी कुंजी सेट नहीं कर सकते। यहाँ क्यों है:

InnoDB MySQL के लिए एकमात्र अंतर्निहित स्टोरेज इंजन है जिसमें विदेशी कुंजियाँ हैं। किसी भी InnoDB तालिका को इंजन = 'InnoDB' के साथ info_schema.tables में पंजीकृत किया जाएगा।

दृश्य, जबकि info_schema.tables में पंजीकृत है, में एक पूर्ण भंडारण इंजन है। MySQL में ऐसी कोई व्यवस्था नहीं है जिसमें किसी अपरिभाषित स्टोरेज इंजन पर विदेशी कुंजियाँ हों।

धन्यवाद!


यह प्रश्न sql सर्वर के बारे में है
जॉर्ज मौअर
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.