提问人:Vincent 提问时间:10/4/2008 最后编辑:Bill Tür stands with UkraineVincent 更新时间:5/23/2023 访问量:1816334
检查 SQL Server 中是否存在表
Check if table exists in SQL Server
问:
我希望这是关于如何使用 SQL 语句检查 SQL Server 2000/2005 中是否存在表的最终讨论。
这里有两种可能的方法。哪一个是标准/最好的方法?
第一种方式:
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;
第二种方式:
IF OBJECT_ID (N'mytablename', N'U') IS NOT NULL
SELECT 1 AS res ELSE SELECT 0 AS res;
MySQL提供了简单的
SHOW TABLES LIKE '%tablename%';
陈述。我正在寻找类似的东西。
答:
使用信息架构是 SQL 标准方法,因此所有支持它的数据库都应该使用它。请参阅此答案中的方法 1。
评论
从我记事起,我们就一直使用这种风格OBJECT_ID
IF OBJECT_ID('*objectName*', 'U') IS NOT NULL
评论
OBJECT_ID('TableName', 'U')
IF EXISTS
对于这样的查询,最好始终使用视图。这些视图(大部分)是许多不同数据库中的标准视图,并且很少因版本而异。INFORMATION_SCHEMA
要检查表是否存在,请使用:
IF (EXISTS (SELECT *
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA = 'TheSchema'
AND TABLE_NAME = 'TheTable'))
BEGIN
--Do Stuff
END
评论
SELECT * FROM tempdb.INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = 'TheSchema' AND TABLE_NAME LIKE '#TheTable%'
如果需要处理不同的数据库:
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 OBJECT_ID('tempdb..#test') is not null
--- temp table exists
评论
ERROR 1305 (42000): FUNCTION table1.OBJECT_ID does not exist
10.5.17-MariaDB-1:10.5.17+maria~ubu2004
我知道这是一个老问题,但如果你打算经常打电话,我发现了这种可能性。
create procedure Table_Exists
@tbl varchar(50)
as
return (select count(*) from sysobjects where type = 'U' and name = @tbl)
go
评论
sysname
varchar(50)
sysobjects
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
在上面的代码中,表名是 .Mapping_APCToFANavigator
评论
{ }
查找其他数据库上的表:
if exists (select * from MyOtherDatabase.sys.tables where name = 'MyTable')
print 'Exists'
假设在一个数据库中,您有一个表 T1。你想在其他数据库上运行脚本,比如 - 如果 t1 存在,那么什么都不做,创建 t1。 为此,请打开 Visual Studio 并执行以下操作:
右键单击 t1,然后单击“将表脚本为”,然后单击 DROP 和“创建到”,然后单击“新建查询编辑器”
您将找到所需的查询。但在执行该脚本之前,不要忘记注释掉查询中的 drop 语句,因为如果已经有一个,则不想创建一个新语句。
谢谢
评论
IF EXISTS
(
SELECT *
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA = 'PutSchemaHere'
AND
TABLE_NAME = 'PutTableNameHere'
)
IF OBJECT_ID('mytablename') IS NOT NULL
如果有人试图在 linq to sql(尤其是 linqpad)中执行相同的操作,请打开选项以包含系统表和视图,然后执行以下代码:
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
假设您有一个对象,其名称位于名为 item 的属性中,并且该架构位于名为 schema 的属性中,其中源变量名称为a
select name from SysObjects where xType='U' and name like '%xxx%' order by name
对于尚未找到解决方案的任何人来说,需要了解的重要信息是:SQL server != MYSQL。 如果你想用MYSQL来做,这很简单
$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";
在这里发布这个,因为它是谷歌的热门。
评论
如果这是“终极”讨论,那么应该注意的是,如果服务器是链接的,Larry Leonard 的脚本也可以查询远程服务器。
if exists (select * from REMOTE_SERVER.MyOtherDatabase.sys.tables where name = 'MyTable')
print 'Exists'
评论
您可以使用以下命令:
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
请参阅以下方法,
方法 1:使用 INFORMATION_SCHEMA。TABLES 视图
我们可以编写如下查询来检查当前数据库中是否存在 Customers 表。
IF EXISTS (SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = N'Customers')
BEGIN
PRINT 'Table Exists'
END
方法 2:使用 OBJECT_ID() 函数
我们可以像下面这样使用 OBJECT_ID() 函数来检查当前数据库中是否存在 Customers 表。
IF OBJECT_ID(N'dbo.Customers', N'U') IS NOT NULL
BEGIN
PRINT 'Table Exists'
END
方法 3:使用 sys。对象目录视图
我们可以使用 Sys.Objects 目录视图来检查表是否存在,如下所示:
IF EXISTS(SELECT 1 FROM sys.Objects WHERE Object_id = OBJECT_ID(N'dbo.Customers') AND Type = N'U')
BEGIN
PRINT 'Table Exists'
END
方法 4:使用 sys.表目录视图
我们可以使用 Sys.Tables 目录视图来检查表是否存在,如下所示:
IF EXISTS(SELECT 1 FROM sys.Tables WHERE Name = N'Customers' AND Type = N'U')
BEGIN
PRINT 'Table Exists'
END
方法 5:避免使用 sys.sysobjects 系统表
我们应该避免直接使用 sys.sysobjects 系统表,在 Sql Server 的某些未来版本中将不推荐直接访问它。根据Microsoft BOL链接,Microsoft建议直接使用目录视图sys.objects/sys.tables而不是sys.sysobjects系统表。
IF EXISTS(SELECT name FROM sys.sysobjects WHERE Name = N'Customers' AND xtype = N'U')
BEGIN
PRINT 'Table Exists'
END
来源:http://sqlhints.com/2014/04/13/how-to-check-if-a-table-exists-in-sql-server/
评论
只是在这里添加,以使开发人员和其他 DBA 受益
接收@Tablename作为参数的脚本
(可能包含也可能不包含 schemaname),如果 schema.table 存在,则返回以下信息:
the_name object_id the_schema the_table the_type
[Facts].[FactBackOrder] 758293761 Facts FactBackOrder Table
每次需要测试表或视图是否存在时,我都会生成此脚本,以便在其他脚本中使用,当确实存在时,将其object_id用于其他目的。
当您传递空字符串、错误的架构名称或错误的表名称时,它会引发错误。
例如,这可能位于过程内部并返回 -1。
例如,我的一个 Data Warehouse 数据库中有一个名为“Facts.FactBackOrder”的表。
我是这样实现的:
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
评论
dbo.[hello.world ]
THE_NAME
sysname', yet you try to squeeze 2
.
在 SQL Server 2000 中,您可以尝试:
IF EXISTS(SELECT 1 FROM sysobjects WHERE type = 'U' and name = 'MYTABLENAME')
BEGIN
SELECT 1 AS 'res'
END
只是想提一种情况,使用该方法可能会更容易一些。视图是每个数据库下的对象 -OBJECT_ID
INFORMATION_SCHEMA
信息架构视图在名为 INFORMATION_SCHEMA。此架构包含在每个数据库中。
https://msdn.microsoft.com/en-us/library/ms186778.aspx
因此,您使用
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;
只会反映 .如果要检查另一个数据库中的表是否存在,而不每次都动态更改,则可以开箱即用。前任-[database]
[database]
OBJECT_ID
IF OBJECT_ID (N'db1.schema.table1', N'U') IS NOT NULL
SELECT 1 AS res ELSE SELECT 0 AS res;
效果也一样好
IF OBJECT_ID (N'db2.schema.table1', N'U') IS NOT NULL
SELECT 1 AS res ELSE SELECT 0 AS res;
SQL SERVER 2016 编辑:
从 2016 年开始,Microsoft 通过向语句添加关键字,简化了在删除之前检查不存在对象的功能。例如if exists
drop
drop table if exists mytablename
将在 1 行代码中执行与 / 包装器相同的操作。OBJECT_ID
INFORMATION_SCHEMA
-- --创建过程以检查表是否存在
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 ;
-- --使用方法:检查是否存在表迁移
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
我在从 INFORMATIONAL_SCHEME 和 OBJECT_ID中进行选择时遇到了一些问题。我不知道是ODBC驱动程序的问题还是其他问题。来自 SQL Management Studio 的查询都没问题。
解决方案如下:
SELECT COUNT(*) FROM <yourTableNameHere>
因此,如果查询失败,则数据库中可能没有此类表(或者您没有访问它的权限)。
检查是通过比较处理ODBC驱动程序的SQL执行器返回的值(在我的情况下是整数)来完成的。
if (sqlexec(conectionHandle, 'SELECT COUNT(*) FROM myTable') == -1) {
// myTable doesn't exist..
}
评论
运行以下查询以检查数据库中是否存在该表:
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
您可以使用以下代码
IF (OBJECT_ID('TableName') IS NOT NULL )
BEGIN
PRINT 'Table Exists'
END
ELSE
BEGIN
PRINT 'Table NOT Exists'
END
或
IF (EXISTS (SELECT * FROM sys.tables WHERE [name] = 'TableName'))
BEGIN
PRINT 'Table Exists'
END
ELSE
BEGIN
PRINT 'Table NOT Exists'
END
我在这里以创建一个视图为例。
因为 ALTER/CREATE 命令不能位于 BEGIN/END 块内。在执行创建之前,您需要测试是否存在并删除它
IF Object_ID('TestView') IS NOT NULL
DROP VIEW TestView
GO
CREATE VIEW TestView
as
. . .
GO
如果您担心权限丢失,也可以编写 GRANT 语句的脚本,并在最后重新运行这些语句。
您可以将创建/更改包装成一个字符串并执行 EXEC - 对于大型视图来说,这可能会变得丑陋
DECLARE @SQL as varchar(4000)
-- set to body of view
SET @SQL = 'SELECT X, Y, Z FROM TABLE'
IF Object_ID('TestView') IS NULL
SET @SQL = 'CREATE VIEW TestView AS ' + @SQL
ELSE
SET @SQL = 'ALTER VIEW TestView AS ' + @SQL
还有一个选项可以检查表是否跨数据库存在
IF EXISTS(SELECT 1 FROM [change-to-your-database].SYS.TABLES WHERE NAME = 'change-to-your-table-name')
BEGIN
-- do whatever you want
END
我认为以下查询有效:
IF EXISTS (select * from sys.tables
WHERE name='mytablename' )
BEGIN
print 'table exists in the database'
END
为什么大多数用户说“如果 *** 不是 null”?,尝试“如果 *** 为空”:)
IF OBJECT_ID(N'[dbo].[Error]', N'U') IS null
BEGIN
CREATE TABLE [dbo].[Error](
[id] [int] IDENTITY(1,1) NOT NULL PRIMARY KEY,
[Values] [nvarchar](MAX) NOT NULL,
[Created] [datetimeoffset](0) NOT NULL,
)
END
评论