Controlla se la tabella esiste in SQL Server
-
03-07-2019 - |
Domanda
Vorrei che questa fosse l'ultima discussione su come verificare se esiste una tabella in SQL Server 2000/2005 usando le istruzioni SQL.
Quando cerchi Google per la risposta, ottieni così tante risposte diverse. Esiste un modo ufficiale / retroattivo e compatibile per farlo?
Ecco due possibili modi per farlo. Quale tra i due è il modo migliore / standard di farlo?
Primo modo:
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;
Secondo modo:
IF OBJECT_ID (N'mytablename', N'U') IS NOT NULL
SELECT 1 AS res ELSE SELECT 0 AS res;
MySQL fornisce il semplice
SHOW TABLES LIKE '%tablename%';
dichiarazione. Sto cercando qualcosa di simile.
Soluzione
Per domande come questa è sempre meglio usare una vista INFORMATION_SCHEMA
. Queste visualizzazioni sono (principalmente) standard in molti database diversi e raramente cambiano da versione a versione.
Per verificare l'esistenza di una tabella, utilizzare:
IF (EXISTS (SELECT *
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA = 'TheSchema'
AND TABLE_NAME = 'TheTable'))
BEGIN
--Do Stuff
END
Altri suggerimenti
Si noti inoltre che se per qualsiasi motivo è necessario verificare la presenza di una tabella temporanea, è possibile farlo:
if OBJECT_ID('tempdb..#test') is not null
--- temp table exists
Usiamo sempre lo stile OBJECT_ID
per tutto il tempo che ricordo
IF OBJECT_ID('*objectName*', 'U') IS NOT NULL
Si prega di consultare gli approcci seguenti,
Approccio 1: utilizzo della vista INFORMATION_SCHEMA.TABLES
Possiamo scrivere una query come sotto per verificare se esiste una tabella Clienti nel database corrente.
IF EXISTS (SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = N'Customers')
BEGIN
PRINT 'Table Exists'
END
Approccio 2: utilizzo della funzione OBJECT_ID ()
Possiamo usare la funzione OBJECT_ID () come sotto per verificare se esiste una tabella Clienti nel database corrente.
IF OBJECT_ID(N'dbo.Customers', N'U') IS NOT NULL
BEGIN
PRINT 'Table Exists'
END
Approccio 3: utilizzo di sys.Objects Catalog View
Possiamo usare la vista del catalogo Sys.Objects per verificare l'esistenza della tabella come mostrato di seguito:
IF EXISTS(SELECT 1 FROM sys.Objects WHERE Object_id = OBJECT_ID(N'dbo.Customers') AND Type = N'U')
BEGIN
PRINT 'Table Exists'
END
Approccio 4: utilizzo di sys.Tables Visualizzazione catalogo
Possiamo usare la vista del catalogo Sys.Tables per verificare l'esistenza della tabella come mostrato di seguito:
IF EXISTS(SELECT 1 FROM sys.Tables WHERE Name = N'Customers' AND Type = N'U')
BEGIN
PRINT 'Table Exists'
END
Approccio 5: evitare l'uso della tabella di sistema sys.sysobjects
Dovremmo evitare di usare direttamente la tabella di sistema sys.sysobjects, l'accesso diretto ad esso sarà deprecato in alcune versioni future del server SQL. Come da collegamento Microsoft BOL, Microsoft suggerisce di utilizzare direttamente le viste del catalogo sys.objects / sys.tables anziché la tabella di sistema sys.sysobjects.
IF EXISTS(SELECT name FROM sys.sysobjects WHERE Name = N'Customers' AND xtype = N'U')
BEGIN
PRINT 'Table Exists'
END
riferito da: http://sqlhints.com/2014/04/13/how-to-check-if-a-table-exists-in-sql-server/
Alla ricerca di una tabella su un database diverso:
if exists (select * from MyOtherDatabase.sys.tables where name = 'MyTable')
print 'Exists'
Volevo solo menzionare una situazione in cui sarebbe probabilmente un po 'più semplice utilizzare il metodo OBJECT_ID
. Le viste INFORMATION_SCHEMA
sono oggetti in ciascun database-
Le viste dello schema di informazioni sono definite in uno schema speciale denominato INFORMATION_SCHEMA. Questo schema è contenuto in ciascun database.
https://msdn.microsoft.com/en-us/library/ ms186778.aspx
Pertanto, tutte le tabelle a cui si accede utilizzando
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;
rifletterà solo ciò che è in [database]
. Se si desidera verificare l'esistenza di tabelle in un altro database, senza modificare in modo dinamico [database]
ogni volta, OBJECT_ID
consentirà di farlo della scatola. Ex -
IF OBJECT_ID (N'db1.schema.table1', N'U') IS NOT NULL
SELECT 1 AS res ELSE SELECT 0 AS res;
funziona altrettanto bene
IF OBJECT_ID (N'db2.schema.table1', N'U') IS NOT NULL
SELECT 1 AS res ELSE SELECT 0 AS res;
Modifica SQL SERVER 2016 :
A partire dal 2016, Microsoft ha semplificato la possibilità di verificare la presenza di oggetti inesistenti prima della caduta, aggiungendo le parole chiave se esiste
alle istruzioni drop
. Ad esempio,
drop table if exists mytablename
farà la stessa cosa dei wrapper OBJECT_ID
/ INFORMATION_SCHEMA
, in 1 riga di codice.
IF OBJECT_ID('mytablename') IS NOT NULL
L'uso dello Schema delle informazioni è il modo standard SQL per farlo, quindi dovrebbe essere usato da tutti i database che lo supportano.
Se devi lavorare su database diversi:
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
Qui nel codice sopra, il nome della tabella è Mapping_APCToFANavigator
.
So che è una vecchia domanda, ma ho trovato questa possibilità se prevedi di chiamarla spesso.
create procedure Table_Exists
@tbl varchar(50)
as
return (select count(*) from sysobjects where type = 'U' and name = @tbl)
go
Basta aggiungere qui, a beneficio di sviluppatori e colleghi DBA
uno script che riceve @Tablename come parametro
(che può contenere o meno lo schema) e restituisce le informazioni di seguito se esiste la schema.table:
the_name object_id the_schema the_table the_type
[Facts].[FactBackOrder] 758293761 Facts FactBackOrder Table
Ho prodotto questo script per usarlo all'interno di altri script ogni volta che ho bisogno di verificare se esiste una tabella o una vista e, quando lo fa, ottenere il suo object_id da usare per altri scopi.
Viene generato un errore quando si passa una stringa vuota, un nome di schema errato o un nome di tabella errato.
questo potrebbe essere all'interno di una procedura e restituire -1 per esempio.
Ad esempio, ho una tabella chiamata " Facts.FactBackOrder " in uno dei miei database di Data Warehouse.
Ecco come l'ho raggiunto:
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
In SQL Server 2000 puoi provare:
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
Qualcosa di importante da sapere per chiunque non abbia ancora trovato la propria soluzione: Server SQL! = MYSQL . Se vuoi farlo con MYSQL , è abbastanza semplice
$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";
Pubblicando questo qui perché è il massimo successo su Google.
select name from SysObjects where xType='U' and name like '%xxx%' order by name
- - crea una procedura per verificare se esiste una tabella
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 ;
- - come usare: controlla se esistono migrazioni di tabelle
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
Se qualcuno sta provando a fare la stessa cosa in linq to sql (o in particolare linqpad), attiva l'opzione per includere tabelle e viste di sistema ed eseguire questo codice:
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
dato che hai un oggetto con il nome in una proprietà chiamata item e lo schema in una proprietà chiamata schema in cui il nome della variabile di origine è a
Se questa deve essere la discussione "definitiva", allora si dovrebbe notare che lo script di Larry Leonard può interrogare anche un server remoto se i server sono collegati.
if exists (select * from REMOTE_SERVER.MyOtherDatabase.sys.tables where name = 'MyTable')
print 'Exists'
Ho avuto dei problemi con la selezione tra INFORMATIONAL_SCHEME e OBJECT_ID. Non so se si tratta di un problema con il driver ODBC o qualcosa del genere. Le query di SQL Management Studio, entrambe, andavano bene.
Ecco la soluzione:
SELECT COUNT(*) FROM <yourTableNameHere>
Quindi, se la query fallisce, probabilmente non esiste una tabella di questo tipo nel database (o non si dispone delle autorizzazioni di accesso).
Il controllo viene effettuato confrontando il valore (intero nel mio caso) restituito dall'esecutore SQL che si occupa del driver ODBC ..
if (sqlexec(conectionHandle, 'SELECT COUNT(*) FROM myTable') == -1) {
// myTable doesn't exist..
}
Esegui questa query per verificare se la tabella esiste nel database:
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
considera in un database che hai una tabella t1. si desidera eseguire script su altri database come - se esiste t1, non fare nient'altro creare t1. Per fare questo aprire Visual Studio ed effettuare le seguenti operazioni:
Fai clic con il pulsante destro del mouse su t1, quindi su Tabella script come, quindi su DROP e Crea in, quindi Nuovo editor di query
troverai la query desiderata. Ma prima di eseguire quello script non dimenticare di commentare l'istruzione drop nella query poiché non vuoi crearne uno nuovo se ce n'è già uno.
Grazie