How can I list all foreign keys referencing a given table in SQL Server?

后端 未结 26 2686
梦毁少年i
梦毁少年i 2020-11-22 07:13

I need to remove a highly referenced table in a SQL Server database. How can I get a list of all the foreign key constraints I will need to remove in order to drop the tabl

相关标签:
26条回答
  • 2020-11-22 08:00

    Mysql server has information_schema.REFERENTIAL_CONSTRAINTS table FYI, you can filter it by table name or referenced table name.

    0 讨论(0)
  • 2020-11-22 08:01

    Here's the SQL code I would use.

    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
    

    It's not particularly clear SQL, so let's look at an example.

    So, supposing I wanted to drop the Employees table in Microsoft's beloved Northwind database, but SQL Server told me that one or more Foreign Keys were preventing me from doing this.

    The SQL command above would return these results...

    It shows me that there are 3 Foreign Keys which reference the Employees table. In other words, I wouldn't be allowed to delete (drop) this table until these three Foreign Keys are first deleted.

    In the results, the first row is how the following Foreign Key constraint would be shown in the results.

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

    The second-to-last column shows the SQL command I would need to use to delete one of these Foreign Keys, eg:

    ALTER TABLE [Employees] DROP CONSTRAINT [FK_Employees_Employees]
    

    ...and the right-hand column shows the SQL to create it...

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

    With all of these commands, you have everything you need to delete the relevant Foreign Keys to allow you to delete a table, then recreate them later.

    Phew. Hope this helps.

    0 讨论(0)
  • 2020-11-22 08:01
    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
    
    0 讨论(0)
  • 2020-11-22 08:01

    First

    EXEC sp_fkeys 'Table', 'Schema'
    

    Then use NimbleText to play with your results

    0 讨论(0)
  • 2020-11-22 08:01

    Most preferable answer by @BankZ

    sp_help 'TableName'   
    

    additionally for different schema

    sp_help 'schemaName.TableName'   
    
    0 讨论(0)
  • 2020-11-22 08:03

    I have been using this on 2008 and up. It's similar to some other solutions listed but, the field names are proper cased to handle case specific (LatBin) collations. Additionally, you can feed it a single table name and retrieve just the info for that table.

    -->>SPECIFY THE DESIRED DB
    USE ???
    GO
    
    /*********************************************************************************************
    
        LIST OUT ALL PRIMARY AND FOREIGN KEY CONSTRAINTS IN A DB OR FOR A SPECIFIED TABLE
    
    *********************************************************************************************/
    DECLARE @tblName VARCHAR(255) 
    
    /*******************/
    
        SET @tblName = NULL-->NULL will return all PK/FK constraints for every table in the database
    
    /*******************/
    
    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),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 = @tblName 
                OR O2.name = @tblName
                OR @tblName IS null)
    ORDER BY PKTABLE_NAME,FKTABLE_NAME
    
    0 讨论(0)
提交回复
热议问题