TABLEAU SQL DROP contrainte de clé étrangère
-
21-09-2019 - |
Question
Si je veux supprimer toutes les tables dans ma base de données comme celui-ci, il va prendre soin de la contrainte de clé étrangère? Sinon, comment puis-je prendre soin de cette première?
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]
La solution
Non, cela ne laissera pas tomber votre table s'il y a effectivement des clés étrangères faisant référence à lui.
Pour obtenir toutes les relations clés étrangères référençant 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 instructions SQL pour déposer effectivement les 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')
Autres conseils
Dans SQL Server Management Studio 2008 (R2) et plus récent, vous pouvez cliquer droit sur le
DB -> Tâches -> Générer des scripts
-
Sélectionnez les tables que vous souhaitez supprimer.
-
Sélectionnez "Enregistrer dans une nouvelle fenêtre de requête".
-
Cliquez sur le bouton Avancé.
-
Set Script DROP et CREATE à Script DROP.
-
Set de clés étrangères script à True.
-
Cliquez sur OK.
-
Cliquez sur Suivant -> Suivant -.> Terminer
-
Voir le script, puis Exécuter.
Si vous laissez tomber la table « enfant » d'abord, la clé étrangère sera supprimée ainsi. Si vous essayez de supprimer la table « mère » d'abord, vous obtiendrez un « Impossible de supprimer l'objet « a » car elle est référencée par une contrainte FOREIGN KEY. » erreur.
Voici une autre façon de déposer correctement toutes les tables, en utilisant la procédure de sp_MSdropconstraints
. Le code le plus court que je pouvais penser:
exec sp_MSforeachtable "declare @name nvarchar(max); set @name = parsename('?', 1); exec sp_MSdropconstraints @name";
exec sp_MSforeachtable "drop table ?";
S'il est SQL Server, vous devez supprimer la contrainte avant de pouvoir déposer la table.
Version légèrement plus générique de ce @mark_s affiché, 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 votre nom de la table, et exécuter le résultat de celui-ci.
Voici une autre façon de faire supprimer toutes les contraintes suivies par les tableaux eux-mêmes, en utilisant un truc de concaténation impliquant FOR XML PATH('')
qui permet de fusionner plusieurs lignes d'entrée dans une ligne de sortie. Si le travail sur quoi que ce soit SQL 2005 et plus tard.
Je l'ai laissé les commandes Executer commentées pour la 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)
Voici un script complet pour mettre en œuvre 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
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.
Utilisation de SQL Server Manager vous pouvez déposer les clés étrangères de l'interface utilisateur. Si vous voulez supprimer la table Diary
mais la table utilisateur dispose d'une DiaryId
clé étrangère pointant vers la table de Diary
, vous pouvez étendre (en utilisant le symbole plus) la table de User
puis développez la section Foreign Keys
. Faites un clic droit sur la clé étrangère qui pointe vers la table de journal, puis sélectionnez Delete
. Vous pouvez ensuite développer la section Columns
, faites un clic droit et supprimer la DiaryId
colonne aussi. Ensuite, vous pouvez juste lancer:
drop table Diary
Je sais que votre question réelle est sur la suppression de toutes les tables, donc cela peut ne pas être utile pour ce cas. Cependant, si vous voulez simplement supprimer quelques tables ce qui est utile, je crois (le titre ne mentionne pas explicitement la suppression de toutes les tables).
Si vous êtes sur un serveur MySQL et si vous ne me dérange pas de perdre vos tables, vous pouvez utiliser une requête simple de 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 façon, peu importe dans quel ordre vous utilisez la table que vous interrogez.
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
Si je veux supprimer toutes les tables ma base de données
Alors il est beaucoup plus facile de laisser tomber la base de données entière:
DROP DATABASE WorkerPensions
Si vous voulez DROP
une table qui a été référencé par un autre tableau en utilisant l'utilisation clé étrangère
DROP TABLE *table_name* CASCADE CONSTRAINTS;
Je pense que cela devrait fonctionner pour vous.