SQL Serverにテーブルが存在するかどうかを確認します
-
03-07-2019 - |
質問
これは、SQLステートメントを使用してSQL Server 2000/2005にテーブルが存在するかどうかを確認する方法に関する究極の議論になりたいです。
Googleで回答を得ると、非常に多くの回答が得られます。公式/後方および前方互換性のある方法がありますか?
次の2つの方法があります。 2つのうち、どちらが標準的/最善の方法ですか?
最初の方法:
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;
2番目の方法:
IF OBJECT_ID (N'mytablename', N'U') IS NOT NULL
SELECT 1 AS res ELSE SELECT 0 AS res;
MySQL はシンプルな
を提供しますSHOW TABLES LIKE '%tablename%';
ステートメント。同様のものを探しています。
解決
このようなクエリでは、常に INFORMATION_SCHEMA
ビューを使用するのが最適です。これらのビューは(ほとんど)多くの異なるデータベースで標準であり、バージョンごとに変わることはめったにありません。
テーブルが存在するかどうかを確認するには:
IF (EXISTS (SELECT *
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA = 'TheSchema'
AND TABLE_NAME = 'TheTable'))
BEGIN
--Do Stuff
END
他のヒント
また、何らかの理由で一時テーブルを確認する必要がある場合は、これを実行できることに注意してください:
if OBJECT_ID('tempdb..#test') is not null
--- temp table exists
覚えている限り、常に OBJECT_ID
スタイルを使用します
IF OBJECT_ID('*objectName*', 'U') IS NOT NULL
以下のアプローチをご覧ください
アプローチ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.Objectsカタログビューの使用
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.Tablesカタログビューの使用
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システムテーブルを直接使用することは避けてください。SQLServerの一部の将来のバージョンでは、このテーブルへの直接アクセスは非推奨になります。 Microsoft BOLリンクに従って、Microsoftはsys.sysobjectsシステムテーブルの代わりにカタログビューsys.objects / sys.tablesを直接使用することを提案しています。
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/
別のデータベース上のテーブルを探す:
if exists (select * from MyOtherDatabase.sys.tables where name = 'MyTable')
print 'Exists'
Justは、おそらく 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]
を毎回動的に変更せずに、 another データベースにテーブルが存在するかどうかを確認したい場合、 OBJECT_ID
でこれを実行できます。ボックスの。 Ex-
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
ラッパーと同じことを行います。
IF OBJECT_ID('mytablename') IS NOT NULL
情報スキーマの使用は、SQL標準の方法であるため、それをサポートするすべてのデータベースで使用する必要があります。
異なるデータベースで作業する必要がある場合:
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
上記のコードでは、テーブル名は Mapping_APCToFANavigator
です。
これは古い質問であることは知っていますが、頻繁に電話する場合はこの可能性を見つけました。
create procedure Table_Exists
@tbl varchar(50)
as
return (select count(*) from sysobjects where type = 'U' and name = @tbl)
go
ここに追加するだけで、開発者や他のDBAの利益のために
@Tablenameをパラメーターとして受け取るスクリプト
(schemanameを含む場合と含まない場合があります)、schema.tableが存在する場合は以下の情報を返します:
the_name object_id the_schema the_table the_type
[Facts].[FactBackOrder] 758293761 Facts FactBackOrder Table
テーブルまたはビューが存在するかどうかをテストする必要があるたびに、他のスクリプト内で使用されるこのスクリプトを作成し、存在する場合、そのobject_idを他の目的で使用するように取得します。
空の文字列、間違ったスキーマ名、または間違ったテーブル名を渡すとエラーが発生します。
これはプロシージャ内にあり、たとえば-1を返します。
例として、" Facts.FactBackOrder"というテーブルがあります。データウェアハウスデータベースの1つ。
これは私がこれを達成した方法です:
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
SQL Server 2000 では、次を試すことができます:
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
まだ解決策を見つけていない人にとって知っておくべき重要なこと: SQLサーバー!= 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";
これはGoogleのトップヒットであるため、ここに投稿します。
select name from SysObjects where xType='U' and name like '%xxx%' order by name
--テーブルが存在するかどうかを確認するプロシージャを作成します
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
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というプロパティに名前を持つオブジェクトがあり、source変数名が a
これが「究極の」議論である場合、Larry Leonardのスクリプトは、サーバーがリンクされている場合にもリモートサーバーを照会できることに注意してください。
if exists (select * from REMOTE_SERVER.MyOtherDatabase.sys.tables where name = 'MyTable')
print 'Exists'
INFORMATIONAL_SCHEMEおよびOBJECT_IDから選択する際に問題が発生しました。 ODBCドライバーの問題なのかどうかはわかりません。SQL管理スタジオからのクエリはどちらも大丈夫でした。
解決策は次のとおりです。
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
1つのデータベースにテーブルt1があると考えてください。次のような他のデータベースでスクリプトを実行したい-t1が存在する場合、t1を作成する他の操作は何もしません。 これを行うには、Visual Studioを開き、次の操作を実行します。
t1を右クリックし、[スクリプトテーブルとして]、[DROPおよび作成先]、[新しいクエリエディター]
目的のクエリが見つかります。ただし、そのスクリプトを実行する前に、クエリ内のドロップステートメントをコメントアウトすることを忘れないでください。既に存在する場合は、新しいステートメントを作成したくないためです。
ありがとう