Verifique se a tabela existe e se não existe, crie-a no SQL Server 2008

130

Estou escrevendo um procedimento armazenado no SQL Server 2008. Preciso verificar se existe uma tabela no banco de dados. Caso contrário, preciso criá-lo.

Como eu faço isso?

Prady
fonte
2
Relacionado, se não duplicado: Verifique se a tabela existe no SQL Server .
1
Essa é uma ótima pergunta que todo mundo que trabalha com o SQL Server fará eventualmente. É triste que o SQL Server não tenha o estilo amigável do Oracle CREATE OR REPLACE #
Davos
1
Para o MySQL, você pode usarCREATE TABLE IF NOT EXISTS ...
John Henckel 26/06

Respostas:

148

Algo assim

IF  NOT EXISTS (SELECT * FROM sys.objects 
WHERE object_id = OBJECT_ID(N'[dbo].[YourTable]') AND type in (N'U'))

BEGIN
CREATE TABLE [dbo].[YourTable](
    ....
    ....
    ....
) 

END
SQLMenace
fonte
1
considere respeitosamente algumas alterações (pelo bem do plano de execução) usando um campo indexado em vez de * (object_id é o campo numérico comumente referido nesta tabela) use type = 'U' em vez de digitar (N'U ') (a coluna _type é do tipo char usando Nchar causa uma conversão implícita que geralmente causa problemas com o estimador de cardinalidade)if (not exists (select object_id from sys.objects where object_id = OBJECT_ID(N'[dbo].[client_tgi_g67_period_list]') and type = 'U'))
yeOldeDataSmythe 29/04/19
153

Apenas por contraste, eu gosto de usar a função object_id, como mostrado abaixo. É um pouco mais fácil de ler, e você não precisa se preocupar com sys.objects x sysobjects x sys.all_objects x sys.tables. Forma básica:

IF object_id('MyTable') is not null
    PRINT 'Present!'
ELSE
    PRINT 'Not accounted for'

Obviamente, isso será exibido como "Presente" se houver algum objeto com esse nome. Se você quiser verificar apenas as tabelas, precisará:

IF object_id('MyTable', 'U') is not null
    PRINT 'Present!'
ELSE
    PRINT 'Not accounted for'

Também funciona para tabelas temporárias:

IF object_id('tempdb.dbo.#MyTable') is not null
    PRINT 'Present!'
ELSE
    PRINT 'Not accounted for'
Philip Kelley
fonte
2
Normalmente, vejo o outro método usado (verificando as tabelas do sistema), mas isso parece legível e compacto. existe alguma razão para não preferir esse método à resposta aceita? (Como problemas de compatibilidade com a migração do SQL para diferentes provedores de banco de dados, velocidade, etc.)?
precisa saber é o seguinte
16

Vamos criar um banco de dados de exemplo com uma tabela pelo script abaixo:

CREATE DATABASE Test
GO
USE Test
GO
CREATE TABLE dbo.tblTest (Id INT, Name NVARCHAR(50))

Abordagem 1: Usando a visualização INFORMATION_SCHEMA.TABLES

Podemos escrever uma consulta como abaixo para verificar se existe uma tabela tblTest no banco de dados atual.

IF EXISTS (SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = N'tblTest')
BEGIN
  PRINT 'Table Exists'
END

A consulta acima verifica a existência da tabela tblTest em todos os esquemas no banco de dados atual. Em vez disso, se você quiser verificar a existência da tabela em um esquema especificado e no banco de dados especificado, podemos escrever a consulta acima, como abaixo:

IF EXISTS (SELECT * FROM Test.INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = N'dbo'  AND TABLE_NAME = N'tblTest')
BEGIN
  PRINT 'Table Exists'
END

Prós desta abordagem: as visualizações INFORMATION_SCHEMA são portáveis ​​em diferentes sistemas RDBMS, portanto, a migração para diferentes RDBMS não requer nenhuma alteração.

Abordagem 2: Usando a função OBJECT_ID ()

Podemos usar a OBJECT_ID()função como abaixo para verificar se existe uma tabela tblTest no banco de dados atual.

IF OBJECT_ID(N'dbo.tblTest', N'U') IS NOT NULL
BEGIN
  PRINT 'Table Exists'
END

A especificação das partes Nome do banco de dados e Nome do esquema para o Nome da tabela é opcional. Mas especificar Nome do banco de dados e Nome do esquema fornece uma opção para verificar a existência da tabela no banco de dados especificado e dentro de um esquema especificado, em vez de verificar o banco de dados atual em todos os esquemas. A consulta abaixo mostra que, embora o banco de dados atual seja o banco de dados MASTER, podemos verificar a existência da tblTesttabela no dboesquema no Testbanco de dados.

USE MASTER
GO
IF OBJECT_ID(N'Test.dbo.tblTest', N'U') IS NOT NULL
BEGIN
  PRINT 'Table Exists'
END

Prós: Fácil de lembrar. Um outro ponto notável a ser mencionado sobre a OBJECT_ID()função é: fornece uma opção para verificar a existência da tabela temporária criada no contexto de conexão atual. Todas as outras abordagens verificam a existência da tabela temporária criada em todo o contexto das conexões, em vez de apenas no contexto atual da conexão. A consulta abaixo mostra como verificar a existência de uma tabela temporária usando a OBJECT_ID()função:

CREATE TABLE #TempTable(ID INT)
GO
IF OBJECT_ID(N'TempDB.dbo.#TempTable', N'U') IS NOT NULL
BEGIN
  PRINT 'Table Exists'
END
GO

Abordagem 3: Usando sys.Objects Catalog View

Podemos usar a Sys.Objectsvisualização de catálogo para verificar a existência da tabela, como mostrado abaixo:

IF EXISTS(SELECT 1 FROM sys.Objects WHERE  Object_id = OBJECT_ID(N'dbo.tblTest') AND Type = N'U')
BEGIN
  PRINT 'Table Exists'
END

Abordagem 4: usando o sys.Tables Catalog View

Podemos usar a Sys.Tablesvisualização de catálogo para verificar a existência da tabela, como mostrado abaixo:

IF EXISTS(SELECT 1 FROM sys.Tables WHERE  Name = N'tblTest' AND Type = N'U')
BEGIN
  PRINT 'Table Exists'
END

Sys.TablesA exibição de catálogo herda as linhas da Sys.Objectsexibição de catálogo; a exibição de Sys.objectscatálogo é chamada de exibição base, onde sys.Tablesé chamada de exibição derivada. Sys.Tablesretornará as linhas apenas para os objetos de tabela, enquanto a Sys.Objectexibição, além de retornar as linhas para os objetos de tabela, retorna linhas para os objetos como: procedimento armazenado, visualizações etc.

Abordagem 5: Evite usar a tabela do sistema sys.sysobjects

Devemos evitar o uso sys.sysobjectsdireto da tabela do sistema, pois o acesso direto a ela será preterido em algumas versões futuras do Sql Server. Conforme o link [Microsoft BOL] [1], a Microsoft está sugerindo o uso das visualizações de catálogo em sys.objects/sys.tablesvez da sys.sysobjectstabela do sistema diretamente.

IF EXISTS(SELECT name FROM sys.sysobjects WHERE Name = N'tblTest' AND xtype = N'U')
BEGIN
  PRINT 'Table Exists'
END

Referência: http://sqlhints.com/2014/04/13/how-to-check-if-a-table-exists-in-sql-server/

Vahid Farahmandian
fonte
É importante notar que esta resposta fornece qual abordagem precisa que o banco de dados seja especificado e quais não. Isso é extremamente valioso e, para scripts executados para configurar e atualizar um banco de dados operacional quando houver vários do mesmo banco de dados em execução na mesma instância, essa é a chave! Ótima informação.
Nelda.techspiress
11

EDITADO

Você pode procurar em sys.tables para verificar a tabela de existência desejada:

IF  NOT EXISTS (SELECT * FROM sys.tables
WHERE name = N'YourTable' AND type = 'U')

BEGIN
CREATE TABLE [SchemaName].[YourTable](
    ....
    ....
    ....
) 

END
veljasije
fonte
3
IF (EXISTS (SELECT * 
                 FROM INFORMATION_SCHEMA.TABLES 
                 WHERE  TABLE_NAME = 'd020915'))
BEGIN
  declare @result int
  set @result=1
  select @result as result
END
Vinod kumar
fonte
1
Declare @Username varchar(20)
Set @Username = 'Mike'

if not exists 
(Select * from INFORMATION_SCHEMA.TABLES where TABLE_NAME = 'tblEmp')

Begin
    Create table tblEmp (ID int primary key, Name varchar(50))
    Print (@Username + ' Table created successfully')
End

Else

Begin
    Print (@Username + ' : this Table Already exists in the database')
End
Aamir Shaikh
fonte
1
Bem-vindo ao StackOverflow. Ao responder perguntas, considere adicionar uma explicação também. O código sozinho não é muito útil na maioria das vezes.
Viktor
0

Tente a seguinte instrução para verificar a existência de uma tabela no banco de dados:

If not exists (select name from sysobjects where name = 'tablename')

Você pode criar a tabela dentro do bloco if.

Só você
fonte
3
Embora essa sintaxe funcione, sysobjectsé uma visão de compatibilidade que existe apenas para evitar a quebra de código antigo. Minha sugestão seria usar modos de exibição de catálogo do sistema (por exemplo sys.objects, sys.tables) para código que apenas segmentará instâncias do SQL Server 2008 e modos de exibição de esquema de informações (por exemplo information_schema.tables) para código que precisa ser portátil. Você pode encontrar mais informações sobre os diferentes pontos de vista aqui: Consultando o Catálogo SQL Server System
AJK
-2

Se não estou errado, isso deve funcionar:

    if not exists (Select 1 from tableName)
create table ...
RAM
fonte
2
e se a tabela existe, mas está vazio ,, este será verdadeira nesse caso
SQLMenace
@SQLMeance Ah, ok, entendi pela sua resposta que você está verificando o tipo 'U' em sys.objects, você poderia me ajudar a entender por que você recomenda isso? e uma tabela pode existir em outro lugar? Agradecemos antecipadamente
RAM