1418 Stimmen

Prüfen, ob die Tabelle in SQL Server existiert

Ich möchte, dass dies die ultimative Diskussion darüber ist, wie man überprüft, ob eine Tabelle in SQL Server 2000/2005 mit SQL-Anweisungen existiert.

Wenn man nach der Antwort googelt, bekommt man so viele verschiedene Antworten. Gibt es eine offizielle/abwärts- und vorwärtskompatible Methode, dies zu tun?

Hier sind zwei Möglichkeiten, wie man das machen kann. Welcher der beiden Wege ist der Standard bzw. der beste Weg, dies zu tun?

Erster Weg:

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;

Zweiter Weg:

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

MySQL bietet die einfache

SHOW TABLES LIKE '%tablename%'; 

Erklärung. Ich bin auf der Suche nach etwas Ähnlichem.

2 Stimmen

Warum ist es am besten, INFORMATION_SCHEMA.TABLES anstelle von sys.tables zu verwenden und dann nach dem Namen zu filtern und vielleicht eine type_desc-Wertprüfung hinzuzufügen?

10voto

Even Mien Punkte 41507

Wenn Sie mit verschiedenen Datenbanken arbeiten müssen:

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

3 Stimmen

Sind Sie sicher? Das Informationsschema auf meiner 2005er Box gibt nur den aktuellen Katalog zurück.

7voto

dko Punkte 866

Ich weiß, es ist eine alte Frage, aber ich habe diese Möglichkeit gefunden, wenn Sie vorhaben, sie oft aufzurufen.

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

10 Stimmen

-1. Es ist sinnlos, dafür eine Prozedur zu haben, da der Aufruf und die Rückgabe genauso viel Code erfordert wie die einfache Auswahl. Sollte verwenden sysname Datentyp nicht varchar(50) . Sollte nicht veraltet sein sysobjects Ansicht und nimmt keine Rücksicht auf das Schema.

5voto

Marcello Miorelli Punkte 2983

Ich füge hier nur etwas hinzu, um Entwicklern und anderen DBAs zu helfen

ein Skript, das @Tabellenname als Parameter erhält

(die den Schemanamen enthalten kann, aber nicht muss) und gibt die folgende Information zurück, wenn die schema.table existiert:

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

Ich habe dieses Skript erstellt, um es innerhalb anderer Skripte jedes Mal zu verwenden, wenn ich testen muss, ob eine Tabelle oder Ansicht existiert oder nicht, und wenn dies der Fall ist, seine object_id zu erhalten, um sie für andere Zwecke zu verwenden.

Es wird ein Fehler ausgegeben, wenn entweder eine leere Zeichenkette, ein falscher Schemaname oder ein falscher Tabellenname übergeben wird.

dies könnte innerhalb einer Prozedur sein und z.B. -1 zurückgeben.

Ich habe zum Beispiel eine Tabelle mit dem Namen "Facts.FactBackOrder" in einer meiner Data Warehouse-Datenbanken.

So habe ich dies erreicht:

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

0 Stimmen

Ihr Skript enthält eine Reihe von Annahmen. Ich könnte zum Beispiel einfach eine Tabelle namens dbo.[hello.world ] und das Skript konnte es aus verschiedenen Gründen nicht finden. Abgesehen davon ist es unwahrscheinlich, dass jemand eine solche Tabelle erstellen möchte, aber trotzdem. Wie auch immer, Ihr THE_NAME Spalte ist definiert als sysname', yet you try to squeeze 2 sysname'-Spalten und einem Punkt ( . ), die alle in eckigen Klammern stehen... das wird eines Tages schiefgehen!

0 Stimmen

@deroby Ich stimme zu, dass sysname nicht der beste Datentyp ist, der verwendet werden sollte, aber das Skript läuft schon seit langem ohne Fehler, ich würde nur dann Zeit darauf verwenden, wenn ich eine vernünftige Situation finde, in der es nicht funktioniert. Noch besser, Sie nehmen diesen Code, verbessern ihn und posten ihn hier als Antwort und ich werde ihn testen, wenn er funktioniert, werde ich Ihre Antwort hochstufen.

4voto

Ich kontrolliere immer auf diese Weise.

IF OBJECT_ID('TestXML..tblCustomer') IS NOT NULL  
BEGIN  
    PRINT 'Exist'
END  
ELSE
BEGIN
    PRINT 'Not Exist'
END 

Gracias

0 Stimmen

Das bringt nichts Neues/unterscheidet sich nicht von den anderen Antworten

4voto

Moccassin Punkte 159
IF EXISTS 
(
    SELECT  * 

    FROM    INFORMATION_SCHEMA.TABLES 

    WHERE   TABLE_SCHEMA = 'PutSchemaHere'     
            AND  
            TABLE_NAME   = 'PutTableNameHere'
)

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X