Vérifiez si la table existe et si elle n'existe pas, créez-la dans SQL Server 2008


130

J'écris une procédure stockée dans SQL Server 2008. Je dois vérifier si une table existe dans la base de données. Si ce n'est pas le cas, je dois le créer.

Comment puis-je faire cela?


2
Associé, sinon dupliqué: vérifiez si la table existe dans SQL Server .

1
C'est une excellente question que tous ceux qui travaillent avec SQL Server se poseront éventuellement. Il est triste que SQL Server n'ait pas le style convivial Oracle CREATE OR REPLACE
Davos

1
Pour MySQL, vous pouvez utiliserCREATE TABLE IF NOT EXISTS ...
John Henckel

Réponses:


148

Quelque chose comme ça

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

1
considérez respectueusement quelques changements (pour le bien du plan d'exécution) en utilisant un champ indexé au lieu de * (object_id est le champ numérique généralement mentionné dans ce tableau) utilisez type = 'U' au lieu de type in (N'U ') (la colonne _type est de type char utilisant Nchar provoque une conversion implicite qui pose souvent des problèmes avec l'estimateur de cardinalité)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

Juste pour le contraste, j'aime utiliser la fonction object_id comme indiqué ci-dessous. C'est un peu plus facile à lire, et vous n'avez pas à vous soucier de sys.objects vs sysobjects vs sys.all_objects vs sys.tables. Forme basique:

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

Bien sûr, cela montrera comme "Présent" s'il y a un objet présent avec ce nom. Si vous souhaitez vérifier uniquement les tableaux, vous aurez besoin de:

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

Cela fonctionne également pour les tables temporaires:

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

2
Je vois généralement l'autre méthode utilisée (vérifier les tables sys) mais cela semble plus lisible et compact. y a-t-il une raison de ne pas préférer cette méthode à la réponse acceptée? (Tels que les problèmes de compatibilité avec la migration SQL vers différents fournisseurs de bases de données, la vitesse, etc.)?
jedd.ahyoung

16

Créons un exemple de base de données avec une table par le script ci-dessous:

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

Approche 1: Utilisation de la vue INFORMATION_SCHEMA.TABLES

Nous pouvons écrire une requête comme ci-dessous pour vérifier si une table tblTest existe dans la base de données actuelle.

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

La requête ci-dessus vérifie l'existence de la table tblTest sur tous les schémas de la base de données actuelle. Au lieu de cela, si vous souhaitez vérifier l'existence de la table dans un schéma spécifié et la base de données spécifiée, nous pouvons écrire la requête ci-dessus comme ci-dessous:

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

Avantages de cette approche: les vues INFORMATION_SCHEMA sont portables sur différents systèmes SGBDR, donc le portage vers différents SGBDR ne nécessite aucune modification.

Approche 2: Utilisation de la fonction OBJECT_ID ()

Nous pouvons utiliser la OBJECT_ID()fonction comme ci-dessous pour vérifier si une table tblTest existe dans la base de données actuelle.

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

La spécification des parties Nom de la base de données et Nom du schéma pour le nom de la table est facultative. Mais la spécification du nom de la base de données et du nom du schéma fournit une option pour vérifier l'existence de la table dans la base de données spécifiée et dans un schéma spécifié, au lieu de vérifier la base de données actuelle sur tous les schémas. La requête ci-dessous montre que même si la base de données actuelle est la base de données MASTER, nous pouvons vérifier l'existence de la tblTesttable dans le dboschéma dans la Testbase de données.

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

Avantages: Facile à retenir. Un autre point notable à mentionner à propos de la OBJECT_ID()fonction est: il fournit une option pour vérifier l'existence de la table temporaire qui est créée dans le contexte de connexion actuel. Toutes les autres approches vérifient l'existence de la table temporaire créée dans tous les contextes de connexions au lieu de simplement le contexte de connexion actuel. La requête ci-dessous montre comment vérifier l'existence d'une table temporaire à l'aide de la OBJECT_ID()fonction:

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

Approche 3: Utilisation de la vue catalogue sys.Objects

Nous pouvons utiliser la Sys.Objectsvue catalogue pour vérifier l'existence de la table comme indiqué ci-dessous:

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

Approche 4: Utilisation de la vue catalogue sys.Tables

Nous pouvons utiliser la Sys.Tablesvue catalogue pour vérifier l'existence de la table comme indiqué ci-dessous:

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

Sys.Tablesla vue de catalogue hérite des lignes de la Sys.Objectsvue de catalogue, la vue de Sys.objectscatalogue est appelée vue de base où elle sys.Tablesest appelée vue dérivée. Sys.Tablesretournera les lignes uniquement pour les objets Table alors que la Sys.Objectvue en plus de renvoyer les lignes pour les objets table, elle renvoie des lignes pour les objets tels que: procédure stockée, vues, etc.

Approche 5: éviter d'utiliser la table système sys.sysobjects

Nous devrions éviter d'utiliser sys.sysobjectsdirectement System Table, l'accès direct à celui-ci sera obsolète dans certaines versions futures du serveur SQL. Conformément au lien [Microsoft BOL] [1], Microsoft suggère d'utiliser les vues de catalogue sys.objects/sys.tablesau lieu de la sys.sysobjectstable système directement.

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

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


Il est important de noter que cette réponse indique quelle approche nécessite la spécification de la base de données et laquelle non. Ceci est extrêmement précieux et pour les scripts qui s'exécutent pour configurer et mettre à jour une base de données opérationnelle lorsqu'il y a plusieurs de la même base de données en cours d'exécution sur la même instance, c'est la clé! Excellente information.
Nelda.techspiress

11

ÉDITÉ

Vous pouvez consulter sys.tables pour vérifier l'existence de la table souhaitée:

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

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

END

3
IF (EXISTS (SELECT * 
                 FROM INFORMATION_SCHEMA.TABLES 
                 WHERE  TABLE_NAME = 'd020915'))
BEGIN
  declare @result int
  set @result=1
  select @result as result
END

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

1
Bienvenue dans StackOverflow. Lorsque vous répondez aux questions, pensez également à ajouter une explication. Le code seul n'est pas très utile la plupart du temps.
Viktor

0

Essayez l'instruction suivante pour vérifier l'existence d'une table dans la base de données:

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

Vous pouvez créer la table à l'intérieur du bloc if.


3
Bien que cette syntaxe fonctionne, il sysobjectsexiste une vue de compatibilité qui n'existe que pour éviter de casser du code plus ancien. Ma suggestion serait de vues du catalogue système d'utilisation (par exemple sys.objects, sys.tables) pour le code qui ne cibleront les instances SQL Server 2008, et des vues de schéma d'information (par exemple information_schema.tables) pour le code qui doit être portable. Vous pouvez trouver plus d'informations sur les différentes vues ici: Interrogation du catalogue système SQL Server
ajk

-2

Si je ne me trompe pas, cela devrait fonctionner:

    if not exists (Select 1 from tableName)
create table ...

2
Et si la table existe mais est vide, ce sera vrai dans ce cas
SQLMenace

@SQLMeance Oh ok, je comprends de votre réponse que vous vérifiez le type 'U' dans sys.objects, pourriez-vous m'aider à comprendre pourquoi vous recommandez cela? et une table peut-elle exister ailleurs? Merci d'avance
RaM
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.