Вопрос

Если я захочу удалить все таблицы в моей базе данных подобным образом, позаботится ли это об ограничении внешнего ключа?Если нет, то как мне позаботиться об этом в первую очередь?

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]
Это было полезно?

Решение

Нет, это не приведет к удалению вашей таблицы, если на нее действительно ссылаются внешние ключи.

Чтобы получить все отношения внешнего ключа, ссылающиеся на вашу таблицу, вы можете использовать этот SQL (если вы используете SQL Server 2005 и более поздние версии):

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

и если таковые имеются, с помощью этого оператора вы можете создавать операторы SQL, чтобы фактически удалить эти отношения 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')

Другие советы

В SQL Server Management Studio 2008 (R2) и более поздних версиях вы можете щелкнуть правой кнопкой мыши

БД -> Задачи -> Генерировать скрипты

  • Выберите таблицы, которые вы хотите УДАЛИТЬ.

  • Выберите «Сохранить в новом окне запроса».

  • Нажмите кнопку «Дополнительно».

  • Установите для параметра Script DROP и CREATE значение Script DROP.

  • Установите для внешних ключей сценария значение True.

  • Нажмите ОК.

  • Нажмите Далее -> Далее -> Готово.

  • Просмотрите сценарий, а затем выполните.

Если вы сначала удалите "дочернюю" таблицу, внешний ключ также будет удален.Если вы попытаетесь сначала удалить "родительскую" таблицу, вы получите сообщение "Не удалось удалить объект "a", поскольку на него ссылается ограничение ВНЕШНЕГО КЛЮЧА". ошибка.

Вот еще один способ правильно удалить все таблицы, используя sp_MSdropconstraints процедура.Самый короткий код, который я мог придумать:

exec sp_MSforeachtable "declare @name nvarchar(max); set @name = parsename('?', 1); exec sp_MSdropconstraints @name";
exec sp_MSforeachtable "drop table ?";

Если это SQL Server, вы должны удалить ограничение, прежде чем сможете удалить таблицу.

Немного более общая версия того, что опубликовал @mark_s, это мне помогло.

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')

просто укажите имя вашей таблицы и выполните ее результат.

Вот еще один способ удалить все ограничения, за которыми следуют сами таблицы, используя трюк конкатенации, включающий FOR XML PATH('') который позволяет объединить несколько входных строк в одну выходную строку.Должно работать с чем угодно SQL 2005 и более поздних версий.

В целях безопасности я оставил команды EXECUTE закомментированными.

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)

Вот полный сценарий для реализации решения:

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.

Используя диспетчер SQL Server, вы можете удалить ограничения внешнего ключа из пользовательского интерфейса.Если вы хотите удалить таблицу Diary но таблица User имеет внешний ключ DiaryId указывая на Diary таблицу, вы можете развернуть (с помощью символа плюса) User таблицу, а затем разверните Foreign Keys раздел.Щелкните правой кнопкой мыши внешний ключ, указывающий на таблицу дневника, затем выберите Delete.Затем вы можете расширить Columns раздел, щелкните правой кнопкой мыши и удалите столбец DiaryId слишком.Тогда вы можете просто запустить:

drop table Diary

Я знаю, что ваш настоящий вопрос касается удаления всех таблиц, поэтому в этом случае это может оказаться бесполезным.Однако, если вы просто хотите удалить несколько таблиц, я считаю, что это полезно (в заголовке явно не упоминается удаление всех таблиц).

Если вы находитесь на сервере MySQL и не против потерять свои таблицы, вы можете использовать простой запрос для одновременного удаления нескольких таблиц:

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

Таким образом, не имеет значения, в каком порядке вы используете таблицу в запросе.

Если кто-нибудь скажет что-нибудь о том, что это не очень хорошее решение, если у вас есть база данных с множеством таблиц:Я согласен!

Если я хочу удалить все таблицы в моей базе данных

Тогда намного проще удалить всю базу данных целиком:

DROP DATABASE WorkerPensions

Если вы хотите DROP таблица, на которую ссылается другая таблица с использованием внешнего ключа

DROP TABLE *table_name* CASCADE CONSTRAINTS;
Я думаю, это должно сработать для вас.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top