SQL DROP TABLE foreign key constraint

si je veux supprimer toutes les tables dans ma base de données comme ceci, va-t-il prendre soin de la contrainte de clé étrangère? Si ce n'est pas le cas, comment dois-je m'en occuper en premier?

GO
IF OBJECT_ID('dbo.[Course]','U') IS NOT NULL
    DROP TABLE dbo.[Course]
GO
IF OBJECT_ID('dbo.[Student]','U') IS NOT NULL
    DROP TABLE dbo.[Student]
117
demandé sur Sam 2009-11-21 20:15:07

12 réponses

Non, cela ne laissera pas tomber votre table si il ya effectivement des clés étrangères de référence.

pour obtenir toutes les relations de clés étrangères se référant à votre table, vous pouvez utiliser ce SQL (si vous êtes sur SQL Server 2005 et plus):

SELECT * 
FROM sys.foreign_keys
WHERE referenced_object_id = object_id('Student')

et s'il y en a, avec cette déclaration ici, vous pouvez créer des déclarations SQL pour réellement laisser tomber ces relations FK:

SELECT 
    'ALTER TABLE [' +  OBJECT_SCHEMA_NAME(parent_object_id) +
    '].[' + OBJECT_NAME(parent_object_id) + 
    '] DROP CONSTRAINT [' + name + ']'
FROM sys.foreign_keys
WHERE referenced_object_id = object_id('Student')
271
répondu marc_s 2017-04-27 09:25:31

dans SQL Server Management Studio 2008 (R2) et plus récent, vous pouvez faire un clic droit sur le

DB -> Tâches -> Générer des Scripts

  • sélectionnez les tableaux que vous voulez supprimer.

  • Sélectionnez "Enregistrer dans une nouvelle fenêtre de requête".

  • cliquez sur le bouton Avancé.

  • Set Script DROP et CREATE to Script DROP.

  • Ensemble de Script de Clés Étrangères pour Vrai.

  • cliquez sur OK.

  • Cliquez Sur Suivant -> Suivant -> Terminer.

  • visualisez le script et exécutez.

30
répondu Riaan 2016-12-16 10:21:02

Si vous laissez tomber le "enfant" table d'abord, la clé étrangère sera abandonnée. Si vous tentez de supprimer la table "parent" en premier, vous obtiendrez un "ne peut pas supprimer l'objet 'a' parce qu'il est référencé par une contrainte de clé étrangère." erreur.

15
répondu Philip Kelley 2009-11-21 17:24:20

Voici une autre façon de supprimer toutes les tables correctement, en utilisant la procédure sp_MSdropconstraints . Le code le plus court que j'ai pu imaginer:

exec sp_MSforeachtable "declare @name nvarchar(max); set @name = parsename('?', 1); exec sp_MSdropconstraints @name";
exec sp_MSforeachtable "drop table ?";
10
répondu Krait 2014-10-13 20:04:55

si C'est SQL Server, vous devez laisser tomber la contrainte avant de pouvoir laisser tomber la table.

2
répondu Shiraz Bhaiji 2009-11-21 17:23:18

version légèrement plus générique de ce que @mark_s a posté, cela m'a aidé

SELECT 
'ALTER TABLE ' +  OBJECT_SCHEMA_NAME(k.parent_object_id) +
'.[' + OBJECT_NAME(k.parent_object_id) + 
'] DROP CONSTRAINT ' + k.name
FROM sys.foreign_keys k
WHERE referenced_object_id = object_id('your table')

il suffit de brancher le nom de votre table et d'exécuter le résultat.

2
répondu Stas Svishov 2015-06-09 13:03:38

Voici une autre façon de supprimer toutes les contraintes suivies par les tables elles-mêmes, en utilisant un truc de concaténation impliquant FOR XML PATH('') qui permet de fusionner plusieurs lignes d'entrée en une seule ligne de sortie. Devrait fonctionner sur quelque chose SQL 2005 et plus tard.

j'ai laissé les commandes EXECUTE commentées pour plus de sécurité.

DECLARE @SQL NVARCHAR(max)
;WITH fkeys AS (
    SELECT quotename(s.name) + '.' + quotename(o.name) tablename, quotename(fk.name) constraintname 
    FROM sys.foreign_keys fk
    JOIN sys.objects o ON fk.parent_object_id = o.object_id
    JOIN sys.schemas s ON o.schema_id = s.schema_id
)
SELECT @SQL = STUFF((SELECT '; ALTER TABLE ' + tablename + ' DROP CONSTRAINT ' + constraintname
FROM fkeys
FOR XML PATH('')),1,2,'')

-- EXECUTE(@sql)

SELECT @SQL = STUFF((SELECT '; DROP TABLE ' + quotename(TABLE_SCHEMA) + '.' + quotename(TABLE_NAME) 
FROM INFORMATION_SCHEMA.TABLES 
FOR XML PATH('')),1,2,'')

-- EXECUTE(@sql)
1
répondu Warren Rumak 2013-12-12 21:57:52

voici un script complet pour implémenter une solution:

create Procedure [dev].DeleteTablesFromSchema
(
    @schemaName varchar(500)
)
As 
begin
    declare @constraintSchemaName nvarchar(128), @constraintTableName nvarchar(128),  @constraintName nvarchar(128)
    declare @sql nvarchar(max)
    -- delete FK first
    declare cur1 cursor for
    select distinct 
    CASE WHEN t2.[object_id] is NOT NULL  THEN  s2.name ELSE s.name END as SchemaName,
    CASE WHEN t2.[object_id] is NOT NULL  THEN  t2.name ELSE t.name END as TableName,
    CASE WHEN t2.[object_id] is NOT NULL  THEN  OBJECT_NAME(d2.constraint_object_id) ELSE OBJECT_NAME(d.constraint_object_id) END as ConstraintName
    from sys.objects t 
        inner join sys.schemas s 
            on t.[schema_id] = s.[schema_id]
        left join sys.foreign_key_columns d 
            on  d.parent_object_id = t.[object_id]
        left join sys.foreign_key_columns d2 
            on  d2.referenced_object_id = t.[object_id]
        inner join sys.objects t2 
            on  d2.parent_object_id = t2.[object_id]
        inner join sys.schemas s2 
            on  t2.[schema_id] = s2.[schema_id]
    WHERE t.[type]='U' 
        AND t2.[type]='U'
        AND t.is_ms_shipped = 0 
        AND t2.is_ms_shipped = 0 
        AND s.Name=@schemaName
    open cur1
    fetch next from cur1 into @constraintSchemaName, @constraintTableName, @constraintName
    while @@fetch_status = 0
    BEGIN
        set @sql ='ALTER TABLE ' + @constraintSchemaName + '.' + @constraintTableName+' DROP CONSTRAINT '+@constraintName+';'
        exec(@sql)
        fetch next from cur1 into @constraintSchemaName, @constraintTableName, @constraintName
    END
    close cur1
    deallocate cur1

    DECLARE @tableName nvarchar(128)
    declare cur2 cursor for
    select s.Name, p.Name
    from sys.objects p
        INNER JOIN sys.schemas s ON p.[schema_id] = s.[schema_id]
    WHERE p.[type]='U' and is_ms_shipped = 0 
    AND s.Name=@schemaName
    ORDER BY s.Name, p.Name
    open cur2

    fetch next from cur2 into @schemaName,@tableName
    while @@fetch_status = 0
    begin
        set @sql ='DROP TABLE ' + @schemaName + '.' + @tableName
        exec(@sql)
        fetch next from cur2 into @schemaName,@tableName
    end

    close cur2
    deallocate cur2

end
go
1
répondu Roman Pokrovskij 2015-05-11 19:27:44

si je veux supprimer tous les tableaux dans ma base de données

alors il est beaucoup plus facile de laisser tomber la base de données entière:

DROP DATABASE WorkerPensions
0
répondu Andomar 2009-11-21 18:03:20
Removing Referenced FOREIGN KEY Constraints
Assuming there is a parent and child table Relationship in SQL Server:

--First find the name of the Foreign Key Constraint:
  SELECT * 
  FROM sys.foreign_keys
  WHERE referenced_object_id = object_id('States')

--Then Find foreign keys referencing to dbo.Parent(States) table:
   SELECT name AS 'Foreign Key Constraint Name', 
           OBJECT_SCHEMA_NAME(parent_object_id) + '.' + OBJECT_NAME(parent_object_id) AS 'Child Table'
   FROM sys.foreign_keys 
   WHERE OBJECT_SCHEMA_NAME(referenced_object_id) = 'dbo' AND 
              OBJECT_NAME(referenced_object_id) = 'dbo.State'

 -- Drop the foreign key constraint by its name 
   ALTER TABLE dbo.cities DROP CONSTRAINT FK__cities__state__6442E2C9;

 -- You can also use the following T-SQL script to automatically find 
 --and drop all foreign key constraints referencing to the specified parent 
 -- table:

 BEGIN

DECLARE @stmt VARCHAR(300);

-- Cursor to generate ALTER TABLE DROP CONSTRAINT statements  
 DECLARE cur CURSOR FOR
 SELECT 'ALTER TABLE ' + OBJECT_SCHEMA_NAME(parent_object_id) + '.' + 
 OBJECT_NAME(parent_object_id) +
                ' DROP CONSTRAINT ' + name
 FROM sys.foreign_keys 
 WHERE OBJECT_SCHEMA_NAME(referenced_object_id) = 'dbo' AND 
            OBJECT_NAME(referenced_object_id) = 'states';

 OPEN cur;
 FETCH cur INTO @stmt;

 -- Drop each found foreign key constraint 
  WHILE @@FETCH_STATUS = 0
  BEGIN
    EXEC (@stmt);
    FETCH cur INTO @stmt;
  END

  CLOSE cur;
  DEALLOCATE cur;

  END
  GO

--Now you can drop the parent table:

 DROP TABLE states;
--# Command(s) completed successfully.
0
répondu CodeTzu 2017-10-23 05:36:06

si cela ne vous dérange pas de perdre vos tables, vous pouvez utiliser une simple requête pour supprimer plusieurs tables à la fois:

SET foreign_key_checks = 0;
DROP TABLE IF EXISTS table_a,table_b,table_c,table_etc;
SET foreign_key_checks = 1;

De cette manière, il n'a pas d'importance dans quel ordre vous utilisez la table dans votre requête.

si quelqu'un va dire quelque chose sur le fait que ce n'est pas une bonne solution si vous avez une base de données avec de nombreuses tables: je suis d'accord!

-2
répondu Els den Iep 2016-07-19 16:07:00

si vous voulez DROP un tableau qui a été référencé par un autre tableau utilisant la clé étrangère utilisation

DROP TABLE *table_name* CASCADE CONSTRAINTS;

Je pense que cela devrait fonctionner pour vous.

-3
répondu Nitish 2015-12-04 07:21:32