it-swarm.asia

تحقق من وجود جدول في SQL Server

أود أن يكون هذا هو المناقشة النهائية حول كيفية التحقق من وجود جدول في 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%'; 

بيان. أنا أبحث عن شيء مماثل.

985
Vincent

بالنسبة لاستعلامات كهذه ، من الأفضل دائمًا استخدام عرض INFORMATION_SCHEMA. تعد طرق العرض هذه (غالبًا) قياسية عبر العديد من قواعد البيانات المختلفة ونادراً ما تتغير من إصدار إلى إصدار.

للتحقق من وجود جدول ، استخدم:

IF (EXISTS (SELECT * 
                 FROM INFORMATION_SCHEMA.TABLES 
                 WHERE TABLE_SCHEMA = 'TheSchema' 
                 AND  TABLE_NAME = 'TheTable'))
BEGIN
    --Do Stuff
END
1191
akmad

لاحظ أيضًا أنه إذا كنت بحاجة إلى التحقق من وجود جدول مؤقت لأي سبب من الأسباب ، يمكنك القيام بذلك:

if OBJECT_ID('tempdb..#test') is not null
 --- temp table exists
249
James Bloomer

نستخدم دائمًا نمط OBJECT_ID لطالما أتذكر

IF OBJECT_ID('*objectName*', 'U') IS NOT NULL 
210
Bob King

يرجى الاطلاع على النهج أدناه ،

النهج 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/

107
BrainCoder

تبحث عن جدول في قاعدة بيانات مختلفة:

if exists (select * from MyOtherDatabase.sys.tables where name = 'MyTable')
    print 'Exists'
34
Larry Leonard

أردت فقط أن أذكر موقفًا واحدًا حيث سيكون من الأسهل قليلاً استخدام طريقة 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 ، في سطر واحد من التعليمات البرمجية.

https://blogs.msdn.Microsoft.com/sqlserverstorageengine/2015/11/03/drop-if-exists-new-thing-in-sql-server-2016/

22
iliketocode
IF OBJECT_ID('mytablename') IS NOT NULL 
20
sansalk

استخدام مخطط المعلومات هو طريقة SQL القياسية للقيام بذلك ، لذلك يجب استخدامه من قبل جميع قواعد البيانات التي تدعمه.

15
Vinko Vrsalovic

إذا كنت بحاجة إلى العمل على قواعد بيانات مختلفة:

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
10
Even Mien
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.

10
dilip kumar singh

أعلم أنه سؤال قديم ولكنني وجدت هذا الاحتمال إذا كنت تخطط للاتصال به كثيرًا.

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

مجرد إضافة هنا ، لصالح المطورين وزملاء 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 
5
marcello miorelli

في SQL Server 2000 يمكنك تجربة:

IF EXISTS(SELECT 1 FROM sysobjects WHERE type = 'U' and name = 'MYTABLENAME')
BEGIN
   SELECT 1 AS 'res' 
END
4
dipi evil
    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
3
BTE
IF EXISTS 
(
    SELECT  * 

    FROM    INFORMATION_SCHEMA.TABLES 

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

شيء مهم يجب معرفته لأي شخص لم يجد حله بعد: 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.

2
Blauhirn
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
1
Krishnaraj Barvathaya
select name from SysObjects where xType='U' and name like '%xxx%' order by name
1
MarceloMadnezz

- - إنشاء إجراء للتحقق من وجود جدول


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);
0
Mathieu Dierckx

إذا كانت هذه هي المناقشة "النهائية" ، فيجب الإشارة إلى أن نص لاري ليونارد يمكنه الاستعلام عن خادم بعيد وكذلك إذا كانت الخوادم مرتبطة.

if exists (select * from REMOTE_SERVER.MyOtherDatabase.sys.tables where name = 'MyTable')
    print 'Exists'
0
user3651072

إذا كان أي شخص يحاول القيام بنفس الشيء في 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

0
Maslow

واجهت بعض المشكلات إما عند التحديد من 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..
}
0
Michael Quad

قم بتشغيل هذا الاستعلام للتحقق مما إذا كان الجدول موجودًا في قاعدة البيانات:

IF(SELECT TABLE_NAME from INFORMATION_SCHEMA.TABLES where TABLE_NAME = 'YourTableName') IS NOT NULL
PRINT 'Table Exists';
0
S Krishna