Question

Je voudrais que ce soit l'ultime discussion sur la manière de vérifier si une table existe dans SQL Server 2000/2005 à l'aide d'instructions SQL.

Lorsque vous recherchez une réponse sur Google, vous obtenez une multitude de réponses différentes. Existe-t-il une manière de le faire compatible avec l’arrière, l’arrière et l’avant?

Voici deux manières possibles de le faire. Lequel des deux est le moyen standard / le meilleur moyen de le faire?

Première manière:

IF EXISTS (SELECT 1 
           FROM INFORMATION_SCHEMA.TABLES 
           WHERE TABLE_TYPE='BASE TABLE' 
           AND TABLE_NAME='mytablename') 
   SELECT 1 AS res ELSE SELECT 0 AS res;

Deuxième voie:

IF OBJECT_ID (N'mytablename', N'U') IS NOT NULL 
   SELECT 1 AS res ELSE SELECT 0 AS res;

MySQL fournit la simplicité

SHOW TABLES LIKE '%tablename%'; 

déclaration. Je cherche quelque chose de similaire.

Était-ce utile?

La solution

Pour les requêtes de ce type, il est toujours préférable d'utiliser une vue INFORMATION_SCHEMA . Ces vues sont (généralement) standard dans de nombreuses bases de données et changent rarement de version à version.

Pour vérifier s'il existe une table, utilisez:

IF (EXISTS (SELECT * 
                 FROM INFORMATION_SCHEMA.TABLES 
                 WHERE TABLE_SCHEMA = 'TheSchema' 
                 AND  TABLE_NAME = 'TheTable'))
BEGIN
    --Do Stuff
END

Autres conseils

Notez également que si, pour une raison quelconque, vous devez rechercher une table temporaire, vous pouvez le faire:

if OBJECT_ID('tempdb..#test') is not null
 --- temp table exists

Nous utilisons toujours le style OBJECT_ID aussi longtemps que je me souvienne

IF OBJECT_ID('*objectName*', 'U') IS NOT NULL 

Veuillez consulter les approches ci-dessous,

Approche 1: utilisation de la vue INFORMATION_SCHEMA.TABLES

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

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

Approche 2: utilisation de la fonction OBJECT_ID ()

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

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

Approche 3: utilisation de la vue catalogue sys.Objects

Nous pouvons utiliser la vue catalogue Sys.Objects 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.Customers') AND Type = N'U')
BEGIN
   PRINT 'Table Exists'
END

Approche 4: utilisation de la vue catalogue sys.Tables

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

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

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

Nous devrions éviter d’utiliser directement la table système sys.sysobjects. Son accès direct sera obsolète dans certaines versions futures du serveur SQL. Selon le lien Microsoft BOL, Microsoft suggère d’utiliser directement les vues de catalogue sys.objects / sys.tables au lieu de la table système sys.sysobjects.

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

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

Recherche d'une table sur une autre base de données:

if exists (select * from MyOtherDatabase.sys.tables where name = 'MyTable')
    print 'Exists'

Je voulais juste mentionner une situation dans laquelle il serait probablement un peu plus facile d'utiliser la méthode OBJECT_ID . Les vues INFORMATION_SCHEMA sont des objets situés sous chaque base de données -

  

Les vues de schéma d’information sont définies dans un schéma spécial nommé   INFORMATION_SCHEMA. Ce schéma est contenu dans chaque base de données.

https://msdn.microsoft.com/en-us/library/ ms186778.aspx

Par conséquent, toutes les tables auxquelles vous accédez à l'aide de

IF EXISTS (SELECT 1 
           FROM [database].INFORMATION_SCHEMA.TABLES 
           WHERE TABLE_TYPE='BASE TABLE' 
           AND TABLE_NAME='mytablename') 
   SELECT 1 AS res ELSE SELECT 0 AS res;

ne reflétera que ce qui se trouve dans [base de données] . Si vous souhaitez vérifier s'il existe des tables dans une autre base de données, sans changer dynamiquement le [base de données] à chaque fois, OBJECT_ID vous permettra de le faire. de la boîte. Ex -

IF OBJECT_ID (N'db1.schema.table1', N'U') IS NOT NULL 
   SELECT 1 AS res ELSE SELECT 0 AS res;

fonctionne aussi bien que

IF OBJECT_ID (N'db2.schema.table1', N'U') IS NOT NULL 
   SELECT 1 AS res ELSE SELECT 0 AS res;

Édition de SQL SERVER 2016 :

À partir de 2016, Microsoft a simplifié la possibilité de rechercher des objets inexistants avant de les déposer, en ajoutant les mots clés s'il existe aux instructions drop . Par exemple,

drop table if exists mytablename

fera la même chose que les wrappers OBJECT_ID / INFORMATION_SCHEMA , sur une ligne de code.

https://blogs.msdn.microsoft.com/sqlserverstorageengine/2015/11/03/drop-if-exists-new-thing-in-server-sql-2016/

IF OBJECT_ID('mytablename') IS NOT NULL 

L’utilisation du schéma d’information est la méthode standard de SQL. Elle doit donc être utilisée par toutes les bases de données qui le prennent en charge.

Si vous devez travailler sur différentes bases de données:

DECLARE @Catalog VARCHAR(255)
SET @Catalog = 'MyDatabase'

DECLARE @Schema VARCHAR(255)
SET @Schema = 'dbo'

DECLARE @Table VARCHAR(255)
SET @Table = 'MyTable'

IF (EXISTS (SELECT * FROM INFORMATION_SCHEMA.TABLES   
    WHERE TABLE_CATALOG = @Catalog 
      AND TABLE_SCHEMA = @Schema 
      AND TABLE_NAME = @Table))
BEGIN
   --do stuff
END
IF EXISTS 
(
    SELECT   * 
    FROM     sys.objects 
    WHERE    object_id = OBJECT_ID(N'[dbo].[Mapping_APCToFANavigator]') 
             AND 
             type in (N'U')
)
BEGIN

    -- Do whatever you need to here.

END

Ici, dans le code ci-dessus, le nom de la table est Mapping_APCToFANavigator .

Je sais que c’est une vieille question, mais j’ai trouvé cette possibilité si vous envisagez de l’appeler souvent.

create procedure Table_Exists
@tbl varchar(50)
as
return (select count(*) from sysobjects where type = 'U' and name = @tbl)
go

Il suffit d'ajouter ici, pour le bénéfice des développeurs et des autres administrateurs de base de données

un script qui reçoit @Tablename en tant que paramètre

(qui peut ou non contenir le nom de fichier) et renvoie les informations ci-dessous si le fichier schema.table existe:

the_name                object_id   the_schema  the_table       the_type
[Facts].[FactBackOrder] 758293761   Facts       FactBackOrder   Table

J'ai créé ce script pour qu'il soit utilisé dans d'autres scripts chaque fois que je dois tester l'existence d'une table ou d'une vue et obtenir son object_id pour qu'il soit utilisé à d'autres fins.

Il génère une erreur lorsque vous transmettez une chaîne vide, un nom de schéma incorrect ou un nom de table incorrect.

cela pourrait être à l'intérieur d'une procédure et renvoyer -1 par exemple.

À titre d'exemple, j'ai une table appelée "Facts.FactBackOrder". dans l'une de mes bases de données d'entrepôt de données.

Voici comment j'ai réalisé ceci:

PRINT 'THE SERVER IS ' + @@SERVERNAME
--select db_name()
PRINT 'THE DATABASE IS ' + db_NAME() 
PRINT ''
GO

SET NOCOUNT ON
GO

--===================================================================================
-- @TableName is the parameter
-- the object we want to deal with (it might be an indexed view or a table)
-- the schema might or might not be specified
-- when not specified it is DBO
--===================================================================================

DECLARE @TableName SYSNAME

SELECT @TableName = 'Facts.FactBackOrder'
--===================================================================================
--===================================================================================
DECLARE @Schema SYSNAME
DECLARE @I INT
DECLARE @Z INT 

SELECT @TableName = LTRIM(RTRIM(@TableName))
SELECT @Z = LEN(@TableName)

IF (@Z = 0) BEGIN

            RAISERROR('Invalid @Tablename passed.',16,1)

END 

SELECT @I = CHARINDEX('.',@TableName )
--SELECT @TableName ,@I

IF @I > 0 BEGIN

        --===================================================================================
        -- a schema and table name have been passed
        -- example Facts.FactBackOrder 
        -- @Schema = Fact
        -- @TableName = FactBackOrder
        --===================================================================================

   SELECT @Schema    = SUBSTRING(@TABLENAME,1,@I-1)
   SELECT @TableName = SUBSTRING(@TABLENAME,@I+1,@Z-@I)



END
ELSE BEGIN

        --===================================================================================
        -- just a table name have been passed
        -- so the schema will be dbo
        -- example Orders
        -- @Schema = dbo
        -- @TableName = Orders
        --===================================================================================

   SELECT @Schema    = 'DBO'     


END

        --===================================================================================
        -- Check whether the @SchemaName is valid in the current database
        --===================================================================================

IF NOT EXISTS ( SELECT * FROM INFORMATION_SCHEMA.SCHEMATA K WHERE K.[SCHEMA_NAME] = @Schema ) BEGIN

            RAISERROR('Invalid Schema Name.',16,1)

END 

--SELECT @Schema  as [@Schema]
--      ,@TableName as [@TableName]


DECLARE @R1 TABLE (

   THE_NAME SYSNAME
  ,THE_SCHEMA SYSNAME
  ,THE_TABLE SYSNAME
  ,OBJECT_ID INT
  ,THE_TYPE SYSNAME
  ,PRIMARY KEY CLUSTERED (THE_SCHEMA,THE_NAME)

)

;WITH RADHE_01 AS (
SELECT QUOTENAME(SCHEMA_NAME(O.schema_id)) + '.' + QUOTENAME(O.NAME) AS [the_name]
      ,the_schema=SCHEMA_NAME(O.schema_id)
      ,the_table=O.NAME
      ,object_id =o.object_id 
      ,[the_type]= CASE WHEN O.TYPE = 'U' THEN 'Table' ELSE 'View' END 
from sys.objects O
where O.is_ms_shipped = 0
AND O.TYPE IN ('U','V')
)
INSERT INTO @R1 (
   THE_NAME 
  ,THE_SCHEMA 
  ,THE_TABLE 
  ,OBJECT_ID
  ,THE_TYPE 
)
SELECT  the_name
       ,the_schema
       ,the_table
       ,object_id
       ,the_type
FROM RADHE_01
WHERE the_schema = @Schema 
  AND the_table  = @TableName

IF (@@ROWCOUNT = 0) BEGIN 

             RAISERROR('Invalid Table Name.',16,1)

END 
ELSE BEGIN

    SELECT     THE_NAME 
              ,THE_SCHEMA 
              ,THE_TABLE 
              ,OBJECT_ID
              ,THE_TYPE 

    FROM @R1

END 

Dans SQL Server 2000 , vous pouvez essayer:

IF EXISTS(SELECT 1 FROM sysobjects WHERE type = 'U' and name = 'MYTABLENAME')
BEGIN
   SELECT 1 AS 'res' 
END
IF EXISTS 
(
    SELECT  * 

    FROM    INFORMATION_SCHEMA.TABLES 

    WHERE   TABLE_SCHEMA = 'PutSchemaHere'     
            AND  
            TABLE_NAME   = 'PutTableNameHere'
)
    IF OBJECT_ID (N'dbo.T', N'U') IS NOT NULL 
      BEGIN 
          print 'deleted table';
          drop table t 
      END
    else 
      begin 
          print 'table not found' 
      end

Create table t (id int identity(1,1) not null, name varchar(30) not null, lastname varchar(25) null)
insert into t( name, lastname) values('john','doe');
insert into t( name, lastname) values('rose',NULL);

Select * from t
1   john    doe
2   rose    NULL

-- clean
drop table t

Quelque chose d’important à savoir pour tous ceux qui n’ont pas encore trouvé la solution: Serveur SQL! = MYSQL . Si vous voulez le faire avec MYSQL , rien de plus simple

    $sql = "SELECT 1 FROM `db_name`.`table_name` LIMIT 1;";
    $result = mysql_query($sql);
    if( $result == false )
        echo "table DOES NOT EXIST";
    else
        echo "table exists";

Publiant ceci ici parce que c'est le top hit chez Google.

select name from SysObjects where xType='U' and name like '%xxx%' order by name

- - crée une procédure pour vérifier si une table existe

DELIMITER $

DROP PROCEDURE IF EXISTS `checkIfTableExists`;

CREATE PROCEDURE checkIfTableExists(
    IN databaseName CHAR(255),
    IN tableName CHAR(255),
    OUT boolExistsOrNot CHAR(40)
)

  BEGIN
      SELECT count(*) INTO boolExistsOrNot FROM information_schema.TABLES
      WHERE (TABLE_SCHEMA = databaseName)
      AND (TABLE_NAME = tableName);
  END $

DELIMITER ;

- - comment utiliser: vérifier si des migrations de table existent

 CALL checkIfTableExists('muDbName', 'migrations', @output);
IF EXISTS (   SELECT * FROM   dbo.sysobjects WHERE  id = OBJECT_ID(N'dbo.TableName') AND OBJECTPROPERTY(id, N'IsUserTable') = 1 )
BEGIN
  SELECT * FROM dbo.TableName;
END
GO

Si quelqu'un essaie de faire la même chose dans linq to SQL (ou en particulier linqpad), activez l'option permettant d'inclure les tables système et les vues et faites le code suivant:

let oSchema = sys.Schemas.FirstOrDefault(s=>s.Name==a.schema )
where oSchema !=null
let o=oSchema!=null?sys.Objects.FirstOrDefault (o => o.Name==a.item && o.Schema_id==oSchema.Schema_id):null
where o!=null

étant donné que vous avez un objet avec le nom dans une propriété appelée item et le schéma dans une propriété appelée schéma où le nom de la variable source est a

S'il s'agit de la discussion "ultime", il convient de noter que le script de Larry Leonard peut également interroger un serveur distant si les serveurs sont liés.

if exists (select * from REMOTE_SERVER.MyOtherDatabase.sys.tables where name = 'MyTable')
    print 'Exists'

J'ai eu quelques problèmes avec la sélection parmi INFORMATIONAL_SCHEME et OBJECT_ID. Je ne sais pas s’il s’agit d’un problème de pilote ODBC ou de quelque chose du genre. Les requêtes du studio de gestion SQL ont été acceptées.

Voici la solution:

SELECT COUNT(*) FROM <yourTableNameHere>

Ainsi, si la requête échoue, il n’ya probablement aucune table de ce type dans la base de données (ou vous n’avez pas les autorisations d’accès à celle-ci).

La vérification est effectuée en comparant la valeur (entier dans mon cas) renvoyée par l'exécuteur SQL qui traite du pilote ODBC.

if (sqlexec(conectionHandle, 'SELECT COUNT(*) FROM myTable') == -1) {
  // myTable doesn't exist..
}

Exécutez cette requête pour vérifier si la table existe dans la base de données:

IF(SELECT TABLE_NAME from INFORMATION_SCHEMA.TABLES where TABLE_NAME = 'YourTableName') IS NOT NULL
PRINT 'Table Exists';
IF EXISTS (
SELECT *
FROM INFORMATION_SCHEMA.TABLES
WHERE 
TABLE_CATALOG = 'Database Name' and
TABLE_NAME = 'Table Name' and 
TABLE_SCHEMA = 'Schema Name') -- Database and Schema name in where statement can be deleted

BEGIN
--TABLE EXISTS
END

ELSE BEGIN
--TABLE DOES NOT EXISTS
END

Considérez dans une base de données que vous avez une table t1. vous voulez exécuter le script sur une autre base de données comme - si t1 existe, ne créez rien d'autre. Pour ce faire, ouvrez visual studio et procédez comme suit:

Cliquez avec le bouton droit sur t1, puis Table de script en tant que, puis DROP et Créer pour, puis Nouvel éditeur de requête

vous trouverez la requête souhaitée. Mais avant d'exécuter ce script, n'oubliez pas de commenter l'instruction drop dans la requête, car vous ne voulez pas en créer une nouvelle s'il en existe déjà une.

Merci

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top