Pergunta

Se eu quiser excluir todas as tabelas do meu banco de dados como este, ele cuidará da restrição de chave estrangeira? Caso contrário, como eu cuido disso primeiro?

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]
Foi útil?

Solução

Não, isso não soltará sua mesa se houver de fato chaves estrangeiras referenciando -a.

Para obter todos os relacionamentos fundamentais para o exterior referenciar sua tabela, você pode usar este SQL (se estiver no SQL Server 2005 e acima):

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

E se houver alguma, com esta declaração aqui, você pode criar declarações SQL para realmente abandonar essas relações 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')

Outras dicas

No SQL Server Management Studio 2008 (R2) e mais recente, você pode clicar com o botão direito do mouse no

Db -> tarefas -> gerar scripts

  • Selecione as tabelas que você deseja soltar.

  • Selecione "Salvar na nova janela de consulta".

  • Clique no botão avançado.

  • Defina a queda de script e crie para queda de script.

  • Defina as chaves estrangeiras do script como True.

  • Clique OK.

  • Clique em Avançar -> Avançar -> Concluir.

  • Veja o script e execute.

Se você soltar a tabela "criança" primeiro, a chave estrangeira também será descartada. Se você tentar soltar a tabela "pai" primeiro, receberá um "não poderá soltar o objeto 'a' porque é referenciado por uma restrição de chave estrangeira". erro.

Aqui está outra maneira de soltar todas as tabelas corretamente, usando sp_MSdropconstraints procedimento. O código mais curto que eu conseguia pensar:

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

Se for o SQL Server, você deverá soltar a restrição antes de poder soltar a tabela.

Versão um pouco mais genérica do que @mark_s postou, isso me ajudou

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

Basta conectar o nome da sua tabela e executar o resultado dele.

Aqui está outra maneira de excluir todas as restrições seguidas pelas mesas, usando um truque de concatenação envolvendo FOR XML PATH('') o que permite a fusão de várias linhas de entrada em uma única linha de saída. Deve trabalhar em qualquer coisa SQL 2005 e mais tarde.

Deixei os comandos executivos comentados por segurança.

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)

Aqui está um script completo para implementar uma solução:

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.

Usando o SQL Server Manager, você pode soltar restrições de chave estrangeira na interface do usuário. Se você quiser excluir a mesa Diary Mas a tabela de usuários tem uma chave estrangeira DiaryId apontando para o Diary Tabela, você pode expandir (usando o símbolo positivo) o User tabela e depois expandir o Foreign Keys seção. Clique com o botão direito do mouse na chave estrangeira que aponta para a tabela do diário e selecione Delete. Você pode expandir o Columns Seção, clique com o botão direito e exclua a coluna DiaryId também. Então você pode simplesmente correr:

drop table Diary

Sei que sua pergunta real é excluir todas as tabelas, então isso pode não ser um útil para esse caso. No entanto, se você deseja apenas excluir algumas tabelas, isso é útil, acredito (o título não menciona explicitamente a exclusão de todas as tabelas).

Se você estiver em um servidor MySQL e se não se importa em perder suas mesas, poderá usar uma consulta simples para excluir várias tabelas de uma só vez:

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

Dessa forma, não importa em que ordem você use a tabela em sua consulta.

Se alguém vai dizer algo sobre o fato de que essa não é uma boa solução se você tiver um banco de dados com muitas tabelas: eu concordo!

Se eu quiser excluir todas as tabelas no meu banco de dados

Então é muito mais fácil soltar todo o banco de dados:

DROP DATABASE WorkerPensions

Se você quiser DROP Uma tabela que foi referenciada por outra tabela usando o uso da chave estrangeira

DROP TABLE *table_name* CASCADE CONSTRAINTS;
Eu acho que deveria funcionar para você.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top