मैं SQL सर्वर में किसी दिए गए तालिका का संदर्भ देने वाली सभी विदेशी कुंजी कैसे सूचीबद्ध कर सकता हूं?




sql-server tsql (14)

@Gishu क्या काम कर रहा था, मैं काम कर रहा था और SQL सर्वर 2005 में निम्न SQL का उपयोग करने में सक्षम था

SELECT t.name AS TableWithForeignKey, fk.constraint_column_id AS FK_PartNo, 
       c.name AS ForeignKeyColumn, o.name AS FK_Name 
  FROM sys.foreign_key_columns AS fk
       INNER JOIN sys.tables AS t ON fk.parent_object_id = t.object_id
       INNER JOIN sys.columns AS c ON fk.parent_object_id = c.object_id 
                                  AND fk.parent_column_id = c.column_id
       INNER JOIN sys.objects AS o ON fk.constraint_object_id = o.object_id
  WHERE fk.referenced_object_id = (SELECT object_id FROM sys.tables 
                                        WHERE name = 'TableOthersForeignKeyInto')
  ORDER BY TableWithForeignKey, FK_PartNo;

जो टेबल, कॉलम और विदेशी कुंजी नामों को 1 क्वेरी में प्रदर्शित करता है।

मुझे एक SQL सर्वर डेटाबेस में एक अत्यधिक संदर्भित तालिका को हटाने की जरूरत है। तालिका को छोड़ने के लिए मुझे उन सभी विदेशी कुंजी बाधाओं की सूची कैसे प्राप्त करनी चाहिए जिन्हें मुझे हटाने की आवश्यकता होगी?

(प्रबंधन स्टूडियो के जीयूआई में क्लिक करने के बारे में एसक्यूएल उत्तर बेहतर है।)


आपको अन्य वस्तुओं के संदर्भों को भी ध्यान में रखना चाहिए।

यदि तालिका को अन्य तालिकाओं द्वारा अत्यधिक संदर्भित किया गया था, तो संभवत: अन्य वस्तुओं जैसे दृश्य, संग्रहित प्रक्रियाओं, कार्यों और अन्य संदर्भों के संदर्भ में भी इसका संदर्भ दिया जाता है।

मैं वास्तव में एसएसएमएस में 'दृश्य निर्भरता' संवाद या एपेक्सएसक्यूएल जैसे मुक्त टूल जैसे जीयूआई उपकरण की सिफारिश करता हूं क्योंकि अन्य ऑब्जेक्ट्स में निर्भरता की खोज करना त्रुटि प्रवण हो सकता है यदि आप इसे केवल SQL के साथ करना चाहते हैं।

यदि एसक्यूएल एकमात्र विकल्प है तो आप इसे ऐसा करने का प्रयास कर सकते हैं।

select O.name as [Object_Name], C.text as [Object_Definition]
from sys.syscomments C
inner join sys.all_objects O ON C.id = O.object_id
where C.text like '%table_name%'

ऊपर कुछ अच्छे जवाब। लेकिन मैं एक प्रश्न के साथ जवाब देना पसंद करता हूं। कोड का यह टुकड़ा sys.sp_helpconstraint (sys proc) से लिया जाता है

टीबीएल से जुड़े विदेशी कुंजी होने पर माइक्रोसॉफ्ट दिखता है।

--setup variables. Just change 'Customer' to tbl you want
declare @objid int,
    @objname nvarchar(776)
select @objname = 'Customer'    
select @objid = object_id(@objname)

if exists (select * from sys.foreign_keys where referenced_object_id = @objid)
    select 'Table is referenced by foreign key' =
        db_name() + '.'
        + rtrim(schema_name(ObjectProperty(parent_object_id,'schemaid')))
        + '.' + object_name(parent_object_id)
        + ': ' + object_name(object_id)
    from sys.foreign_keys 
    where referenced_object_id = @objid 
    order by 1

उत्तर इस तरह दिखेगा: test_db_name.dbo.Account: FK_Account_Customer


चयनित आईडी के लिए सभी जिम्मेदारियों की गणना कैसे करें। बस @dbTableName मान, @dbRowId मान और इसके प्रकार को बदलें (अगर आपको लाइन नंबर 82 में निकालने की आवश्यकता है (..SET @SQL = ..))। का आनंद लें।

DECLARE @dbTableName varchar(max) = 'User'
DECLARE @dbRowId uniqueidentifier = '21d34ecd-c1fd-11e2-8545-002219a42e1c'

DECLARE @FK_ROWCOUNT int
DECLARE @SQL nvarchar(max)

DECLARE @PKTABLE_QUALIFIER sysname
DECLARE @PKTABLE_OWNER sysname
DECLARE @PKTABLE_NAME sysname
DECLARE @PKCOLUMN_NAME sysname
DECLARE @FKTABLE_QUALIFIER sysname
DECLARE @FKTABLE_OWNER sysname
DECLARE @FKTABLE_NAME sysname
DECLARE @FKCOLUMN_NAME sysname
DECLARE @UPDATE_RULE smallint
DECLARE @DELETE_RULE smallint
DECLARE @FK_NAME sysname
DECLARE @PK_NAME sysname
DECLARE @DEFERRABILITY sysname

IF OBJECT_ID('tempdb..#Temp1') IS NOT NULL
    DROP TABLE #Temp1;
CREATE TABLE #Temp1 ( 
    PKTABLE_QUALIFIER sysname,
    PKTABLE_OWNER sysname,
    PKTABLE_NAME sysname,
    PKCOLUMN_NAME sysname,
    FKTABLE_QUALIFIER sysname,
    FKTABLE_OWNER sysname,
    FKTABLE_NAME sysname,
    FKCOLUMN_NAME sysname,
    UPDATE_RULE smallint,
    DELETE_RULE smallint,
    FK_NAME sysname,
    PK_NAME sysname,
    DEFERRABILITY sysname,
    FK_ROWCOUNT int
    );
DECLARE FK_Counter_Cursor CURSOR FOR
    SELECT PKTABLE_QUALIFIER = CONVERT(SYSNAME,DB_NAME()),
       PKTABLE_OWNER = CONVERT(SYSNAME,SCHEMA_NAME(O1.SCHEMA_ID)),
       PKTABLE_NAME = CONVERT(SYSNAME,O1.NAME),
       PKCOLUMN_NAME = CONVERT(SYSNAME,C1.NAME),
       FKTABLE_QUALIFIER = CONVERT(SYSNAME,DB_NAME()),
       FKTABLE_OWNER = CONVERT(SYSNAME,SCHEMA_NAME(O2.SCHEMA_ID)),
       FKTABLE_NAME = CONVERT(SYSNAME,O2.NAME),
       FKCOLUMN_NAME = CONVERT(SYSNAME,C2.NAME),
       -- Force the column to be non-nullable (see SQL BU 325751)
       --KEY_SEQ             = isnull(convert(smallint,k.constraint_column_id), sysconv(smallint,0)),
       UPDATE_RULE = CONVERT(SMALLINT,CASE OBJECTPROPERTY(F.OBJECT_ID,'CnstIsUpdateCascade') 
                                        WHEN 1 THEN 0
                                        ELSE 1
                                      END),
       DELETE_RULE = CONVERT(SMALLINT,CASE OBJECTPROPERTY(F.OBJECT_ID,'CnstIsDeleteCascade') 
                                        WHEN 1 THEN 0
                                        ELSE 1
                                      END),
       FK_NAME = CONVERT(SYSNAME,OBJECT_NAME(F.OBJECT_ID)),
       PK_NAME = CONVERT(SYSNAME,I.NAME),
       DEFERRABILITY = CONVERT(SMALLINT,7)   -- SQL_NOT_DEFERRABLE
    FROM   SYS.ALL_OBJECTS O1,
           SYS.ALL_OBJECTS O2,
           SYS.ALL_COLUMNS C1,
           SYS.ALL_COLUMNS C2,
           SYS.FOREIGN_KEYS F
           INNER JOIN SYS.FOREIGN_KEY_COLUMNS K
             ON (K.CONSTRAINT_OBJECT_ID = F.OBJECT_ID)
           INNER JOIN SYS.INDEXES I
             ON (F.REFERENCED_OBJECT_ID = I.OBJECT_ID
                 AND F.KEY_INDEX_ID = I.INDEX_ID)
    WHERE  O1.OBJECT_ID = F.REFERENCED_OBJECT_ID
           AND O2.OBJECT_ID = F.PARENT_OBJECT_ID
           AND C1.OBJECT_ID = F.REFERENCED_OBJECT_ID
           AND C2.OBJECT_ID = F.PARENT_OBJECT_ID
           AND C1.COLUMN_ID = K.REFERENCED_COLUMN_ID
           AND C2.COLUMN_ID = K.PARENT_COLUMN_ID
           AND O1.NAME = @dbTableName
OPEN FK_Counter_Cursor;
FETCH NEXT FROM FK_Counter_Cursor INTO @PKTABLE_QUALIFIER, @PKTABLE_OWNER, @PKTABLE_NAME, @PKCOLUMN_NAME, @FKTABLE_QUALIFIER, @FKTABLE_OWNER, @FKTABLE_NAME, @FKCOLUMN_NAME, @UPDATE_RULE, @DELETE_RULE, @FK_NAME, @PK_NAME, @DEFERRABILITY;
WHILE @@FETCH_STATUS = 0
   BEGIN
        SET @SQL = 'SELECT @dbCountOut = COUNT(*) FROM [' + @FKTABLE_NAME + '] WHERE [' + @FKCOLUMN_NAME + '] = ''' + CAST(@dbRowId AS varchar(max)) + '''';
        EXECUTE sp_executesql @SQL, N'@dbCountOut int OUTPUT', @dbCountOut = @FK_ROWCOUNT OUTPUT;
        INSERT INTO #Temp1 (PKTABLE_QUALIFIER, PKTABLE_OWNER, PKTABLE_NAME, PKCOLUMN_NAME, FKTABLE_QUALIFIER, FKTABLE_OWNER, FKTABLE_NAME, FKCOLUMN_NAME, UPDATE_RULE, DELETE_RULE, FK_NAME, PK_NAME, DEFERRABILITY, FK_ROWCOUNT) VALUES (@FKTABLE_QUALIFIER, @PKTABLE_OWNER, @PKTABLE_NAME, @PKCOLUMN_NAME, @FKTABLE_QUALIFIER, @FKTABLE_OWNER, @FKTABLE_NAME, @FKCOLUMN_NAME, @UPDATE_RULE, @DELETE_RULE, @FK_NAME, @PK_NAME, @DEFERRABILITY, @FK_ROWCOUNT)
      FETCH NEXT FROM FK_Counter_Cursor INTO @PKTABLE_QUALIFIER, @PKTABLE_OWNER, @PKTABLE_NAME, @PKCOLUMN_NAME, @FKTABLE_QUALIFIER, @FKTABLE_OWNER, @FKTABLE_NAME, @FKCOLUMN_NAME, @UPDATE_RULE, @DELETE_RULE, @FK_NAME, @PK_NAME, @DEFERRABILITY;
   END;
CLOSE FK_Counter_Cursor;
DEALLOCATE FK_Counter_Cursor;
GO
SELECT * FROM #Temp1
GO

मूल प्रश्न ने सभी विदेशी कुंजीों की एक सूची को अत्यधिक संदर्भित तालिका में प्राप्त करने के लिए कहा ताकि तालिका को हटाया जा सके।

यह छोटी क्वेरी सभी विदेशी कुंजी को किसी विशेष तालिका में छोड़ने के लिए आवश्यक सभी 'ड्रॉप विदेशी कुंजी' कमांड लौटाती है:

SELECT 
   'ALTER TABLE ['+sch.name+'].['+referencingTable.Name+'] DROP CONSTRAINT ['+foreignKey.name+']' '[DropCommand]'
FROM sys.foreign_key_columns fk
    JOIN sys.tables referencingTable ON fk.parent_object_id = referencingTable.object_id
    JOIN sys.schemas sch ON referencingTable.schema_id = sch.schema_id
    JOIN sys.objects foreignKey ON foreignKey.object_id = fk.constraint_object_id
    JOIN sys.tables referencedTable ON fk.referenced_object_id = referencedTable.object_id
WHERE referencedTable.name = 'MyTableName'

उदाहरण आउटपुट:

[DropCommand]
ALTER TABLE [dbo].[OtherTable1] DROP CONSTRAINT [FK_OtherTable1_MyTable]
ALTER TABLE [dbo].[OtherTable2] DROP CONSTRAINT [FK_OtherTable2_MyTable]

वर्तमान डेटाबेस में सभी विदेशी कुंजी के लिए ड्रॉप कमांड प्राप्त करने के लिए WHERE-Clause को छोड़ दें।


मैं SQL सर्वर प्रबंधन स्टूडियो में डेटाबेस आरेखण सुविधा का उपयोग करता हूं, लेकिन चूंकि आपने इसे अस्वीकार कर दिया - यह मेरे लिए SQL सर्वर 2008 में काम करता है (2005 नहीं है)।

रेफरिंग टेबल और कॉलम नामों की सूची प्राप्त करने के लिए ...

select 
    t.name as TableWithForeignKey, 
    fk.constraint_column_id as FK_PartNo, c.
    name as ForeignKeyColumn 
from 
    sys.foreign_key_columns as fk
inner join 
    sys.tables as t on fk.parent_object_id = t.object_id
inner join 
    sys.columns as c on fk.parent_object_id = c.object_id and fk.parent_column_id = c.column_id
where 
    fk.referenced_object_id = (select object_id 
                               from sys.tables 
                               where name = 'TableOthersForeignKeyInto')
order by 
    TableWithForeignKey, FK_PartNo

विदेशी कुंजी बाधाओं के नाम प्राप्त करने के लिए

select distinct name from sys.objects where object_id in 
(   select fk.constraint_object_id from sys.foreign_key_columns as fk
    where fk.referenced_object_id = 
        (select object_id from sys.tables where name = 'TableOthersForeignKeyInto')
)

मैं विदेशी कुंजी से संबंधित सभी विवरण खोजने के लिए इस स्क्रिप्ट का उपयोग कर रहा हूं। मैं जानकारी का उपयोग कर रहा हूँ .CHEMA। नीचे एक एसक्यूएल स्क्रिप्ट है:

SELECT 
    ccu.table_name AS SourceTable
    ,ccu.constraint_name AS SourceConstraint
    ,ccu.column_name AS SourceColumn
    ,kcu.table_name AS TargetTable
    ,kcu.column_name AS TargetColumn
FROM INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE ccu
    INNER JOIN INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS rc
        ON ccu.CONSTRAINT_NAME = rc.CONSTRAINT_NAME 
    INNER JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE kcu 
        ON kcu.CONSTRAINT_NAME = rc.UNIQUE_CONSTRAINT_NAME  
ORDER BY ccu.table_name

यह आपको देता है:

  • खुद ही एफके
  • स्कीमा कि एफके से संबंधित है
  • " रेफरेंसिंग टेबल " या तालिका जिसमें एफके है
  • " रेफरेंसिंग कॉलम " या संदर्भ तालिका के अंदर कॉलम जो एफके को इंगित करता है
  • " संदर्भित तालिका " या तालिका जिसमें कुंजी कॉलम है जो आपका एफके इंगित कर रहा है
  • " संदर्भित कॉलम " या कॉलम जो कुंजी है कि आपका एफके इंगित कर रहा है

नीचे कोड:

SELECT  obj.name AS FK_NAME,
    sch.name AS [schema_name],
    tab1.name AS [table],
    col1.name AS [column],
    tab2.name AS [referenced_table],
    col2.name AS [referenced_column]
FROM sys.foreign_key_columns fkc
INNER JOIN sys.objects obj
    ON obj.object_id = fkc.constraint_object_id
INNER JOIN sys.tables tab1
    ON tab1.object_id = fkc.parent_object_id
INNER JOIN sys.schemas sch
    ON tab1.schema_id = sch.schema_id
INNER JOIN sys.columns col1
    ON col1.column_id = parent_column_id AND col1.object_id = tab1.object_id
INNER JOIN sys.tables tab2
    ON tab2.object_id = fkc.referenced_object_id
INNER JOIN sys.columns col2
    ON col2.column_id = referenced_column_id AND col2.object_id = tab2.object_id

यहां उपयोग किया गया एसक्यूएल कोड है।

SELECT 
   f.name AS 'Name of Foreign Key',
   OBJECT_NAME(f.parent_object_id) AS 'Table name',
   COL_NAME(fc.parent_object_id,fc.parent_column_id) AS 'Fieldname',
   OBJECT_NAME(t.object_id) AS 'References Table name',
   COL_NAME(t.object_id,fc.referenced_column_id) AS 'References fieldname',

   'ALTER TABLE [' + OBJECT_NAME(f.parent_object_id) + ']  DROP CONSTRAINT [' + f.name + ']' AS 'Delete foreign key',

   'ALTER TABLE [' + OBJECT_NAME(f.parent_object_id) + ']  WITH NOCHECK ADD CONSTRAINT [' + 
        f.name + '] FOREIGN KEY([' + COL_NAME(fc.parent_object_id,fc.parent_column_id) + ']) REFERENCES ' + 
        '[' + OBJECT_NAME(t.object_id) + '] ([' +
        COL_NAME(t.object_id,fc.referenced_column_id) + '])' AS 'Create foreign key'
    -- , delete_referential_action_desc AS 'UsesCascadeDelete'
FROM sys.foreign_keys AS f,
     sys.foreign_key_columns AS fc,
     sys.tables t 
WHERE f.OBJECT_ID = fc.constraint_object_id
AND t.OBJECT_ID = fc.referenced_object_id
AND OBJECT_NAME(t.object_id) = 'Employees'      --  Just show the FKs which reference a particular table
ORDER BY 2

यह विशेष रूप से स्पष्ट एसक्यूएल नहीं है, तो चलिए एक उदाहरण देखें।

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

ऊपर दिए गए एसक्यूएल कमांड इन परिणामों को वापस कर देगा ...

यह मुझे दिखाता है कि 3 विदेशी कुंजी हैं जो Employees तालिका का संदर्भ देती हैं। दूसरे शब्दों में, मुझे इस तालिका को हटाने (ड्रॉप) करने की अनुमति नहीं दी जाएगी जब तक कि इन तीन विदेशी कुंजी को पहले हटा दिया न जाए।

परिणामों में, पहली पंक्ति यह है कि परिणाम में निम्नलिखित विदेशी कुंजी बाधा दिखाई देगी।

ALTER TABLE [dbo].[Employees]  WITH NOCHECK 
ADD CONSTRAINT [FK_Employees_Employees] FOREIGN KEY([ReportsTo])
REFERENCES [dbo].[Employees] ([EmployeeID])

दूसरा-से-आखिरी कॉलम SQL कमांड दिखाता है जिसे मुझे इन विदेशी कुंजीों में से किसी एक को हटाने के लिए उपयोग करने की आवश्यकता होगी, उदाहरण के लिए:

ALTER TABLE [Employees] DROP CONSTRAINT [FK_Employees_Employees]

... और दायां हाथ कॉलम एसक्यूएल को इसे बनाने के लिए दिखाता है ...

ALTER TABLE [Employees] WITH NOCHECK 
ADD CONSTRAINT [FK_Employees_Employees] 
FOREIGN KEY([ReportsTo]) REFERENCES [Employees] ([EmployeeID])

इन सभी आदेशों के साथ, आपके पास तालिका को हटाने की अनुमति देने के लिए प्रासंगिक विदेशी कुंजी को हटाने के लिए आवश्यक सब कुछ है, फिर बाद में उन्हें पुन: बनाएँ।

ओह। उम्मीद है की यह मदद करेगा।


सहायता के लिए तालिका की सभी विदेशी कुंजी को स्क्रिप्ट कैसे करें देखें।

अद्यतन : लिंक अब उपलब्ध नहीं है लेकिन प्रासंगिक SQL को संबंधित प्रश्न के उत्तर के रूप में कॉपी किया गया था।

आप जीयूआई के माध्यम से निर्भरताओं को भी देख सकते हैं।


निश्चित नहीं है कि किसी ने सुझाव क्यों नहीं दिया है लेकिन मैं किसी दिए गए तालिका के लिए विदेशी कुंजी sp_fkeys लिए sp_fkeys का उपयोग करता sp_fkeys :

EXEC sp_fkeys 'TableName'

 SELECT OBJECT_NAME(fk.parent_object_id) as ReferencingTable, 
        OBJECT_NAME(fk.constraint_object_id) as [FKContraint]
  FROM sys.foreign_key_columns as fk
 WHERE fk.referenced_object_id = OBJECT_ID('ReferencedTable', 'U')

यदि विदेशी कुंजी बाधाएं हैं तो यह केवल रिश्ते को दिखाता है। मेरा डेटाबेस स्पष्ट रूप से एफके बाधा उत्पन्न करता है। कुछ तालिका रेफरेंसियल अखंडता को लागू करने के लिए ट्रिगर्स का उपयोग करती है, और कभी-कभी संबंधों को इंगित करने के लिए समान नामित कॉलम के अलावा कुछ भी नहीं होता है (और बिल्कुल कोई संदर्भित अखंडता नहीं)।

सौभाग्य से, हमारे पास एक सतत नामकरण दृश्य है इसलिए मैं संदर्भ तालिका और इस तरह के विचार ढूंढने में सक्षम हूं:

SELECT OBJECT_NAME(object_id) from sys.columns where name like 'client_id'

मैंने इस स्क्रिप्ट को उत्पन्न करने के आधार के रूप में चुना है जो मुझे संबंधित तालिकाओं पर करने की ज़रूरत है।


SELECT
OBJECT_NAME(parent_object_id) 'Parent table',
c.NAME 'Parent column name',
OBJECT_NAME(referenced_object_id) 'Referenced table',
cref.NAME 'Referenced column name'
FROM 
sys.foreign_key_columns fkc 
INNER JOIN 
sys.columns c 
   ON fkc.parent_column_id = c.column_id 
      AND fkc.parent_object_id = c.object_id
INNER JOIN 
sys.columns cref 
   ON fkc.referenced_column_id = cref.column_id 
      AND fkc.referenced_object_id = cref.object_id  where   OBJECT_NAME(parent_object_id) = 'tablename'

यदि आप सभी तालिकाओं के विदेशी कुंजी संबंध प्राप्त करना चाहते हैं तो where खंड को अन्य टैबलेटनाम के बजाय अपना टैबलेटनाम लिखें


SELECT PKTABLE_QUALIFIER = CONVERT(SYSNAME,DB_NAME()),
       PKTABLE_OWNER = CONVERT(SYSNAME,SCHEMA_NAME(O1.SCHEMA_ID)),
       PKTABLE_NAME = CONVERT(SYSNAME,O1.NAME),
       PKCOLUMN_NAME = CONVERT(SYSNAME,C1.NAME),
       FKTABLE_QUALIFIER = CONVERT(SYSNAME,DB_NAME()),
       FKTABLE_OWNER = CONVERT(SYSNAME,SCHEMA_NAME(O2.SCHEMA_ID)),
       FKTABLE_NAME = CONVERT(SYSNAME,O2.NAME),
       FKCOLUMN_NAME = CONVERT(SYSNAME,C2.NAME),
       -- Force the column to be non-nullable (see SQL BU 325751)
       --KEY_SEQ             = isnull(convert(smallint,k.constraint_column_id), sysconv(smallint,0)),
       UPDATE_RULE = CONVERT(SMALLINT,CASE OBJECTPROPERTY(F.OBJECT_ID,'CnstIsUpdateCascade') 
                                        WHEN 1 THEN 0
                                        ELSE 1
                                      END),
       DELETE_RULE = CONVERT(SMALLINT,CASE OBJECTPROPERTY(F.OBJECT_ID,'CnstIsDeleteCascade') 
                                        WHEN 1 THEN 0
                                        ELSE 1
                                      END),
       FK_NAME = CONVERT(SYSNAME,OBJECT_NAME(F.OBJECT_ID)),
       PK_NAME = CONVERT(SYSNAME,I.NAME),
       DEFERRABILITY = CONVERT(SMALLINT,7)   -- SQL_NOT_DEFERRABLE
FROM   SYS.ALL_OBJECTS O1,
       SYS.ALL_OBJECTS O2,
       SYS.ALL_COLUMNS C1,
       SYS.ALL_COLUMNS C2,
       SYS.FOREIGN_KEYS F
       INNER JOIN SYS.FOREIGN_KEY_COLUMNS K
         ON (K.CONSTRAINT_OBJECT_ID = F.OBJECT_ID)
       INNER JOIN SYS.INDEXES I
         ON (F.REFERENCED_OBJECT_ID = I.OBJECT_ID
             AND F.KEY_INDEX_ID = I.INDEX_ID)
WHERE  O1.OBJECT_ID = F.REFERENCED_OBJECT_ID
       AND O2.OBJECT_ID = F.PARENT_OBJECT_ID
       AND C1.OBJECT_ID = F.REFERENCED_OBJECT_ID
       AND C2.OBJECT_ID = F.PARENT_OBJECT_ID
       AND C1.COLUMN_ID = K.REFERENCED_COLUMN_ID
       AND C2.COLUMN_ID = K.PARENT_COLUMN_ID







tsql