Compruebe si la tabla existe y si no existe, créela en SQL Server 2008

130

Estoy escribiendo un procedimiento almacenado en SQL Server 2008. Necesito verificar si existe una tabla en la base de datos. Si no es así, necesito crearlo.

¿Cómo hago esto?

Prady
fuente
2
Relacionado, si no está duplicado: verifique si la tabla existe en SQL Server .
1
Esta es una gran pregunta que todos los que trabajan con SQL Server se harán eventualmente. Es triste que SQL Server no tenga el estilo amigable de Oracle CREAR O REEMPLAZAR
Davos
1
Para MySQL puede usarCREATE TABLE IF NOT EXISTS ...
John Henckel

Respuestas:

148

Algo como esto

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
fuente
1
considere respetuosamente algunos cambios (por el bien del plan de ejecución) usando un campo indexado en lugar de * (object_id es el campo numérico comúnmente referido en esta tabla) use type = 'U' en lugar de escriba in (N'U ') (la columna _type es de tipo char usando Nchar provoca una conversión implícita que a menudo causa problemas con el estimador de cardinalidad)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
153

Solo por contraste, me gusta usar la función object_id como se muestra a continuación. Es un poco más fácil de leer y no tiene que preocuparse por sys.objects vs. sysobjects vs. sys.all_objects vs. sys.tables. Forma básica:

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

Por supuesto, esto se mostrará como "Presente" si hay algún objeto presente con ese nombre. Si desea verificar solo las tablas, necesitaría:

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

Funciona también para tablas temporales:

IF object_id('tempdb.dbo.#MyTable') is not null
    PRINT 'Present!'
ELSE
    PRINT 'Not accounted for'
Philip Kelley
fuente
2
Por lo general, veo el otro método utilizado (verificando las tablas del sistema) pero parece más legible y compacto. ¿Hay alguna razón para no preferir este método sobre la respuesta aceptada? (Como problemas de compatibilidad con la migración de SQL a diferentes proveedores de bases de datos, velocidad, etc.)
jedd.ahyoung
16

Creemos una base de datos de muestra con una tabla mediante el siguiente script:

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

Enfoque 1: Uso de la vista INFORMATION_SCHEMA.TABLES

Podemos escribir una consulta como la siguiente para verificar si existe una tabla tblTest en la base de datos actual.

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

La consulta anterior verifica la existencia de la tabla tblTest en todos los esquemas de la base de datos actual. En lugar de esto, si desea verificar la existencia de la tabla en un esquema específico y la base de datos especificada, entonces podemos escribir la consulta anterior de la siguiente manera:

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

Ventajas de este enfoque: las vistas INFORMATION_SCHEMA son portables en diferentes sistemas RDBMS, por lo que la transferencia a diferentes RDBMS no requiere ningún cambio.

Enfoque 2: uso de la función OBJECT_ID ()

Podemos usar la OBJECT_ID()función que se muestra a continuación para verificar si existe una tabla tblTest en la base de datos actual.

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

La especificación de las partes Nombre de base de datos y Nombre de esquema para el Nombre de tabla es opcional. Pero especificar el Nombre de la base de datos y el Nombre del esquema proporciona una opción para verificar la existencia de la tabla en la base de datos especificada y dentro de un esquema especificado, en lugar de verificar la base de datos actual en todos los esquemas. La consulta a continuación muestra que aunque la base de datos actual es la base de datos MASTER, podemos verificar la existencia de la tblTesttabla en el dboesquema de la Testbase de datos.

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

Pros: fácil de recordar. Otro punto notable a mencionar sobre la OBJECT_ID()función es: proporciona una opción para verificar la existencia de la Tabla Temporal que se crea en el contexto de conexión actual. Todos los demás enfoques verifican la existencia de la tabla temporal creada en todo el contexto de conexiones en lugar de solo el contexto de conexión actual. La siguiente consulta muestra cómo verificar la existencia de una tabla temporal utilizando la OBJECT_ID()función:

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

Enfoque 3: Uso de sys.Objects Catalog View

Podemos usar la Sys.Objectsvista de catálogo para verificar la existencia de la Tabla como se muestra a continuación:

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

Enfoque 4: Uso de sys. Tablas Vista de catálogo

Podemos usar la Sys.Tablesvista de catálogo para verificar la existencia de la Tabla como se muestra a continuación:

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

Sys.Tablesla vista de catálogo hereda las filas de la Sys.Objectsvista de catálogo, la vista de Sys.objectscatálogo se conoce como vista base, donde sys.Tablesse conoce como vista derivada. Sys.Tablesdevolverá las filas solo para los objetos de la tabla, mientras que Sys.Objectview aparte de devolver las filas para los objetos de la tabla, devuelve filas para los objetos como: procedimiento almacenado, vistas, etc.

Enfoque 5: Evite usar la tabla del sistema sys.sysobjects

Deberíamos evitar el uso de la sys.sysobjectstabla del sistema directamente, el acceso directo a él será obsoleto en algunas versiones futuras del servidor SQL. Según el enlace [Microsoft BOL] [1], Microsoft sugiere utilizar las vistas de catálogo en sys.objects/sys.tableslugar de la sys.sysobjectstabla del sistema directamente.

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

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

Vahid Farahmandian
fuente
Es importante tener en cuenta que esta respuesta proporciona qué enfoque necesita que se especifique la base de datos y cuáles no. Esto es extremadamente valioso y para los scripts que se ejecutan para configurar y actualizar una base de datos operativa cuando hay múltiples de la misma base de datos ejecutándose en la misma instancia, ¡esta es la clave! Gran informacion.
Nelda.techspiress
11

EDITADO

Puede buscar en sys.tables para verificar la existencia de la tabla deseada:

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

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

END
veljasije
fuente
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
fuente
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
fuente
1
Bienvenido a StackOverflow. Al responder preguntas, considere agregar una explicación también. El código solo no es muy útil la mayor parte del tiempo.
Viktor
0

Pruebe la siguiente instrucción para verificar la existencia de una tabla en la base de datos:

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

Puede crear la tabla dentro del bloque if.

Sólo tu
fuente
3
Si bien esa sintaxis funcionará, sysobjectses una vista de compatibilidad que existe solo para evitar romper el código anterior. Mi sugerencia sería usar vistas del catálogo del sistema (por ejemplo sys.objects, sys.tables) para el código que solo apuntará a instancias de SQL Server 2008, y vistas del esquema de información (por ejemplo information_schema.tables) para el código que necesita ser portátil. Puede encontrar más información sobre las diferentes vistas aquí: Consultando el Catálogo del Sistema SQL Server
ajk
-2

Si no me equivoco, esto debería funcionar:

    if not exists (Select 1 from tableName)
create table ...
RAM
fuente
2
¿Qué pasa si la tabla existe pero está vacía? Esto será cierto en ese caso
SQLMenace
@SQLMeance Oh, ok, entiendo por su respuesta que está buscando el tipo 'U' en sys.objects, ¿podría ayudarme a entender, por qué recomienda esto? ¿y puede existir una tabla en otro lugar? Gracias de antemano
RaM