2011-09-30 15 views
8

अगर मैं एक मेज, TableA है:किसी विशिष्ट पंक्ति की विदेशी कुंजी निर्भरताओं को कैसे ढूंढें?

Id 
1 
2 
3 
... 

और दो अन्य तालिकाओं:

TableB:

Id, TableAId 
1 1 
2 1 

TableC:

Id, TableAId 
1, 1 
2, 2 

कहाँ TableAId एक FK संबंध है TableA.Id के साथ।

मैं कैसे निर्धारित करूं कि टेबलए, आईडी 1, में तीन पंक्तियां हैं जो इसकी ओर इशारा करते हैं? और वह टेबलए, आईडी 2 में एक पंक्ति है जो इसे इंगित करती है? और अधिक विशेष रूप से, मैं पहचान कैसे करूं कि वे पंक्तियां क्या हैं? (उनकी तालिका नाम और आईडी)

+0

अपने लक्ष्य पूरी तरह से स्पष्ट नहीं है। क्या आप टेबल के बीच विदेशी कुंजी प्राप्ति जहाजों की पहचान करने के लिए मेटाडेटा खोजना चाहते हैं, या क्या आप टीएसक्यूएल प्रश्नों को डेटा ढूंढने के लिए चाहते हैं जो आपको पहले से ही विदेशी कुंजी संबंधों को जानते हैं? – user957902

+0

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

उत्तर

15

आप पंक्तियों को प्रदर्शित करने के लिए चुनिंदा वक्तव्य उत्पन्न करने के लिए INFORMATION_SCHEMA विचारों का उपयोग कर सकते हैं। मैंने केवल प्रश्न में दिए गए तालिकाओं के खिलाफ इसका परीक्षण किया है, लेकिन इसे उन मामलों में काम करने के लिए विस्तारित किया जा सकता है जहां कुंजी एकाधिक कॉलम हैं।

declare @table_schema nvarchar(50) = 'dbo', 
     @table_name nvarchar(50) = 'TableA', 
     @id int = 1 

select fk_col.TABLE_SCHEMA, fk_col.TABLE_NAME, fk_col.COLUMN_NAME, 
    'select * from ' + fk_col.TABLE_SCHEMA + '.' + fk_col.TABLE_NAME + ' t1 ' 
     + ' inner join ' + @table_schema + '.' + @table_name + ' t2 ' 
     + ' on t1.' + fk_col.COLUMN_NAME + ' = t2.' + pk_col.COLUMN_NAME 
     + ' where t2.' + pk_col.COLUMN_NAME + ' = ' + cast(@id as nvarchar) 

from INFORMATION_SCHEMA.TABLE_CONSTRAINTS pk 

    join INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE pk_col 
     on pk.CONSTRAINT_SCHEMA = pk_col.CONSTRAINT_SCHEMA 
     and pk.CONSTRAINT_NAME = pk_col.CONSTRAINT_NAME 

    join INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS fk 
     on pk.CONSTRAINT_SCHEMA = fk.UNIQUE_CONSTRAINT_SCHEMA 
     and pk.CONSTRAINT_NAME = fk.UNIQUE_CONSTRAINT_NAME 

    join INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE fk_col 
     on fk_col.CONSTRAINT_SCHEMA = fk.CONSTRAINT_SCHEMA 
     and fk_col.CONSTRAINT_NAME = fk.CONSTRAINT_NAME 

where pk.TABLE_SCHEMA = @table_schema 
    and pk.TABLE_NAME = @table_name 
    and pk.CONSTRAINT_TYPE = 'PRIMARY KEY' 

चयन उत्पन्न बयान:

select * from dbo.TableB t1 inner join dbo.TableA t2 on t1.TableAId = t2.Id where t2.Id = 1 
select * from dbo.TableC t1 inner join dbo.TableA t2 on t1.TableAId = t2.Id where t2.Id = 1 

और क्वेरी परिणाम:

Id   TableAId Id 
----------- ----------- ----------- 
1   1   1 
2   1   1 

Id   TableAId Id 
----------- ----------- ----------- 
1   1   1 
+0

महान उत्तर, thx :) – mrzepa

+0

हाय कृपया आप मुझे समकक्ष MySQL कोड दे सकते हैं। –

2

आदेश में पता लगाने के लिए क्या FK संबंधों मौजूद हैं, आप एसक्यूएल सर्वर में sys सूची विचारों का निरीक्षण करने की जरूरत है - की तरह कुछ:

SELECT * 
FROM sys.foreign_keys 
WHERE referenced_object_id = OBJECT_ID('TableA') 

यह सब विदेशी कुंजी बाहर सूची जाएगा संबंध जो TableA पर मौजूद हैं।

एक बार आपके पास यह जानकारी हो जाने के बाद, यह TableA और इनमें से किसी भी अन्य तालिका के बीच एक बहुत ही सरल जॉइन है।

अद्यतन: एक बार जब आप जानते हैं कि उदा। TableB और TableC संदर्भ अपने TableA, तो आप एक साधारण के साथ depdendent पंक्तियों में शामिल हों पा सकते हैं:

SELECT c.* 
FROM dbo.TableC c 
INNER JOIN dbo.TableA a ON a.ID = c.TableAID -- or whatever column joins the tables..... 
WHERE....... -- possibly with a WHERE clause... 
+0

@ किर्कवॉल: हाँ, मुझे पता है - लेकिन डेटा स्तर पर उन अवशेष केवल स्कीमा के आधार पर मौजूद हैं! यदि आपको पता नहीं है ** ** अन्य तालिका संदर्भ 'टेबलए'', आपके पास ** 'कोई रास्ता नहीं है ** यह जानने के लिए ** आपकी अन्य तालिकाओं से ** पंक्तियां ** आपकी पंक्तियों संदर्भ पंक्तियों में संदर्भ पंक्तियां –

+0

I * करें * स्कीमा स्तर पर निर्भरताओं को जानें। लेकिन यह मुझे नहीं बताता कि डेटा निर्भरताओं को कैसे ढूंढें। मैं आश्रित * पंक्ति * कैसे ढूंढूं? और व्यवहार में मेरे पास इस तालिका को इंगित करने वाले लगभग 20-30 टेबल हैं। बड़े पैमाने पर शामिल होना ही एकमात्र तरीका है? –

+1

@ किर्कवॉल: आप डेटा निर्भरताओं को कैसे ढूंढना चाहते हैं, अगर आपको पता नहीं है कि उन पंक्तियों में कौन सी पंक्तियां हो सकती हैं जो आपकी पंक्ति को 'टेबलए' में संदर्भित करती हैं ??? आपको ** स्कीमा निर्भरता ** पहले की आवश्यकता है - ** फिर ** (और केवल तब) क्या आप डेटा निर्भरताओं की तलाश कर सकते हैं .... –

4

मैं इस कंप्यूटर पर एसक्यूएल की जरूरत नहीं है तो मैं आप सटीक कोड नहीं दे सकता लेकिन यहां जिस तरह से आप चाहिए चले जाओ। कृपया ध्यान दें कि मैं SQL सर्वर शब्दावली का उपयोग करूंगा।

मुझे कम से कम SQL सर्वर में गतिशील एसक्यूएल के बिना ऐसा करने का कोई तरीका नहीं दिखता है।

  1. कॉलम FK_TBL_NM, FK_CLMN_VAL साथ अस्थायी तालिका #t बनाएँ।
  2. यह TableA के पी के लिए सभी FK संबंधों प्राप्त करने के लिए मुश्किल नहीं होना चाहिए:

    SELECT * FROM sys.foreign_keys 
    WHERE referenced_object_id = OBJECT_ID('TableA') 
    
  3. उत्पन्न इस क्वेरी की और प्रत्येक के लिए परिणाम के माध्यम से पुनरावृति और गतिशील एसक्यूएल कि में शामिल हो जाएगा निष्पादित करने के लिए एक कर्सर का प्रयोग करें TableA और कर्सर से पुनर्प्राप्त तालिका और FK_TBL_NM (टेबलबी, टेबलसी, ...) और एफके कॉलम का मान देता है।

  4. #t में परिणाम डालें

अब (यह तालिका में गतिशील एसक्यूएल परिणाम प्राप्त लेकिन stackoverflow पर एक अनुसंधान करने के लिए मुश्किल है) आप तालिका TableB में हर पंक्ति में एक पंक्ति है , TableC, ...

मुझे पता है कि यह संभव है क्योंकि मैंने कुछ दिनों पहले काम पर अपने वर्तमान प्रोजेक्ट के लिए समान तर्क के साथ कोड लिखा था।

ध्यान दें कि आपको शायद एक कोड के साथ पीके/एफके के साथ अपना कोड काम करना चाहिए। कॉलम के लिए अलग-अलग डेटा प्रकार भी हैं। यह चीजों को थोड़ा सा जटिल करता है लेकिन यह संभव है।

ऊपर सूचीबद्ध प्रत्येक चरण को लागू करना मुश्किल नहीं है। हालांकि, अगर आपको कोई कठिनाई है, तो स्टैक ओवरफ्लो पर खोजें :)

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