أود أن يكون هذا هو المناقشة النهائية حول كيفية التحقق من وجود جدول في SQL Server 2000/2005 باستخدام بيانات SQL.
عندما تقوم Google بالإجابة ، تحصل على الكثير من الإجابات المختلفة. هل هناك طريقة رسمية/متخلفة ومتقدمة للقيام بذلك؟
فيما يلي طريقتان ممكنتان للقيام بذلك. أي واحد من الاثنين هو المعيار/أفضل طريقة للقيام بذلك؟
الطريقة الأولى:
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;
الخلية يوفر بسيطة
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
يمكننا كتابة استعلام مثل أدناه للتحقق من وجود "جدول العملاء" في قاعدة البيانات الحالية.
IF EXISTS (SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = N'Customers')
BEGIN
PRINT 'Table Exists'
END
الطريقة الثانية: استخدام دالة OBJECT_ID ()
يمكننا استخدام دالة OBJECT_ID () كما هو موضح أدناه للتحقق من وجود "جدول عملاء" في قاعدة البيانات الحالية.
IF OBJECT_ID(N'dbo.Customers', N'U') IS NOT NULL
BEGIN
PRINT 'Table Exists'
END
الطريقة الثالثة: استخدام عرض كتالوج 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
الطريقة الرابعة: استخدام عرض كتالوج sys.Tables
يمكننا استخدام عرض كتالوج Sys.Tables للتحقق من وجود الجدول كما هو موضح أدناه:
IF EXISTS(SELECT 1 FROM sys.Tables WHERE Name = N'Customers' AND Type = N'U')
BEGIN
PRINT 'Table Exists'
END
الطريقة الخامسة: تجنب استخدام sys.sysobjects جدول النظام
يجب أن نتجنب استخدام sys.sysobjects System Table مباشرة ، سيتم إهمال الوصول المباشر إليه في بعض الإصدارات المستقبلية من 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/
تبحث عن جدول في قاعدة بيانات مختلفة:
if exists (select * from MyOtherDatabase.sys.tables where name = 'MyTable')
print 'Exists'
أردت فقط أن أذكر موقفًا واحدًا حيث سيكون من الأسهل قليلاً استخدام طريقة 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
ستفعل نفس الشيء مثل أغلفة 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
مجرد إضافة هنا ، لصالح المطورين وزملاء DBAs
البرنامج النصي الذي يتلقىTablename كمعلمة
(التي قد تحتوي أو لا تحتوي على schemaname) وإرجاع المعلومات أدناه في حالة وجود مخطط:
the_name object_id the_schema the_table the_type
[Facts].[FactBackOrder] 758293761 Facts FactBackOrder Table
لقد قمت بإنتاج هذا البرنامج النصي ليتم استخدامه داخل البرامج النصية الأخرى في كل مرة أحتاج فيها إلى اختبار ما إذا كان هناك جدول أو طريقة عرض موجودة ، وعندما يحدث ذلك ، يجب استخدام object_id الخاص به لأغراض أخرى.
يثير خطأ عند تمرير سلسلة فارغة أو اسم مخطط خاطئ أو اسم جدول خاطئ.
هذا يمكن أن يكون داخل الإجراء والعودة -1 على سبيل المثال.
على سبيل المثال ، لدي جدول يسمى "Facts.FactBackOrder" في إحدى قواعد بيانات Warehouse الخاصة بي.
هذه هي الطريقة التي حققت بها هذا:
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,@[email protected])
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 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
IF EXISTS
(
SELECT *
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA = 'PutSchemaHere'
AND
TABLE_NAME = 'PutTableNameHere'
)
شيء مهم يجب معرفته لأي شخص لم يجد حله بعد: 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";
نشر هذا هنا لأنه الأكثر نجاحًا في Google.
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
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 REMOTE_SERVER.MyOtherDatabase.sys.tables where name = 'MyTable')
print 'Exists'
إذا كان أي شخص يحاول القيام بنفس الشيء في 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
بالنظر إلى أن لديك كائن يحمل الاسم في خاصية تسمى العنصر ، والمخطط في خاصية تسمى المخطط حيث يكون اسم المتغير المصدر a
واجهت بعض المشكلات إما عند التحديد من INFORMATIONAL_SCHEME و OBJECT_ID. لا أعلم ما إذا كانت مشكلة ODBC برنامج التشغيل أو أي شيء آخر .. كانت استفسارات من SQL management studio ، كلاهما ، على ما يرام.
هنا هو الحل:
SELECT COUNT(*) FROM <yourTableNameHere>
لذا ، إذا فشل الاستعلام ، فربما لا يوجد جدول في قاعدة البيانات (أو ليس لديك أذونات الوصول إليه).
يتم التحقق من خلال مقارنة القيمة (عدد صحيح في حالتي) التي يتم إرجاعها بواسطة برنامج تشغيل SQL الذي يتعامل مع ODBC برنامج التشغيل ..
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';