यदि आप एक निश्चित सूचकांक तालिका में मौजूद हैं, तो आप कैसे जांच करेंगे?


288

कुछ इस तरह:

SELECT
* 
FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS 
WHERE CONSTRAINT_NAME ='FK_TreeNodesBinaryAssets_BinaryAssets'
and TABLE_NAME = 'TreeNodesBinaryAssets'

लेकिन अनुक्रमित के लिए।


11
मैं चाहता हूं कि INFORMATION_SCHEMA को वास्तव में सभी स्कीमा जानकारी थी
एलन मैकडोनाल्ड

जवाबों:


480

आप इसे इस तरह से सीधे आगे का चयन करके कर सकते हैं:

SELECT * 
FROM sys.indexes 
WHERE name='YourIndexName' AND object_id = OBJECT_ID('Schema.YourTableName')

76
आप स्टेटमेंट को एक में भी लपेट सकते हैं IF EXISTS(SELECT * ...) BEGIN ... END
बॉउनव

26
यह उल्लेख के लायक है कि YourTableNameस्कीमा के साथ पूरा नाम होना चाहिए
मारेक

2
@blasto यदि आप गैर-डिफ़ॉल्ट स्कीमा का उपयोग करते हैं, जैसे मेरे अधिकांश मामलों में, स्कीमा को निर्दिष्ट करना उपसर्ग अनिवार्य है। अन्य मामलों में, आपको इस प्रश्न में कोई परिणाम नहीं मिलेगा
Marek

3
एक अस्थायी तालिका के खिलाफ जाँच करने के लिए, 'tempdb.sys.indexes' और 'tempdb .. # TableName' का उपयोग कर सकते हैं। (रेफ ब्योर्न डी। जेनसेन )
क्रुकसेक

7
बस जोड़ने के लिए: "SQL सर्वर 2016 से शुरुआत करके आप DROP INDEX IF EXISTS सिंटैक्स का उपयोग कर सकते हैं।" एमएस प्रलेखन
हिंगिंगर

100

के लिए एसक्यूएल 2008 और नए , अधिक संक्षिप्त विधि, कोडिंग के लिहाज से, सूचकांक अस्तित्व का पता लगाने के लिए उपयोग करना है INDEXPROPERTYमें निर्मित समारोह:

INDEXPROPERTY ( object_ID , index_or_statistics_name , property )  

IndexIDसंपत्ति के साथ सबसे सरल उपयोग है :

If IndexProperty(Object_Id('MyTable'), 'MyIndex', 'IndexID') Is Null

यदि सूचकांक मौजूद है, तो उपरोक्त अपनी आईडी लौटा देगा; यदि ऐसा नहीं होता है, तो यह वापस आ जाएगी NULL


71

AdaTheDEV, मैंने आपके सिंटैक्स का उपयोग किया और निम्नलिखित और क्यों बनाया।

समस्या: अनुक्रमणिका गुम होने के कारण एक घंटे में एक बार प्रक्रिया चलती है।

सुधार: अनुक्रमणिका के लिए जाँच करने और इसे बनाने और उसके बाद यदि अनुपस्थित हो, तो क्वेरी प्रक्रिया को बदलने की प्रक्रिया ... एक ही कोड को क्वेरी और प्रक्रिया के अंत में रखा गया है क्योंकि यह आवश्यक नहीं है लेकिन त्रैमासिक है। यहां केवल ड्रॉप सिंटैक्स दिखा रहा है

-- drop the index 
begin

  IF EXISTS (SELECT *  FROM sys.indexes  WHERE name='Index_Name' 
    AND object_id = OBJECT_ID('[SchmaName].[TableName]'))
  begin
    DROP INDEX [Index_Name] ON [SchmaName].[TableName];
  end

end

15

हालांकि मूल प्रश्न से थोड़ा सा विचलन भविष्य के लोगों के लिए उपयोगी साबित हो सकता है , जो चाहते हैं DROPऔर CREATEएक तैनाती स्क्रिप्ट में, यानी एक सूचकांक।

आप अपने चेक स्टेटमेंट में निम्नलिखित जोड़कर मौजूद चेक को बायपास कर सकते हैं:

CREATE INDEX IX_IndexName
ON dbo.TableName
WITH (DROP_EXISTING = ON);

यहाँ और पढ़ें: CREATE INDEX (Transact-SQL) - DROP_EXISTING क्लॉज

NB जैसा कि टिप्पणियों में उल्लेख किया गया है, इस खंड में त्रुटि के बिना काम करने के लिए सूचकांक पहले से मौजूद होना चाहिए।


8
असल में .. सावधान! यदि अनुक्रमणिका पहले से मौजूद नहीं है, तो यह विफल हो जाएगा! कम से कम SQL सर्वर 2008 में।
एंड्री कापोव

1
... और यह अभी भी SQL 2016 में विफल हो जाता है
Magier

2
एक और (शायद स्पष्ट) प्रभाव यह है कि यह सूचकांक को फिर से बनाएगा। यह वह नहीं हो सकता जो आप चाहते हैं। एक बड़ी मेज पर एक सूचकांक को छोड़ना और बनाना एक महंगा ऑपरेशन है - अगर मौजूदा सूचकांक पहले से ही आप चाहते हैं। यह कथन एक-चरणीय प्रतिस्थापन के लिए अच्छा है। यह मौजूदा सूचकांक की तुलना नहीं करता है - बल्कि एक क्रूर बल "ऐसा करें, भले ही विद्यमान हो - इसे ड्रॉप करें ... बस करो, ठीक हो गया!" :-) यह अभी भी सभी जाँच की आवश्यकता है कि ओपी की तलाश थी। हालाँकि, यदि अनुक्रमणिका को प्रतिस्थापित करने की आवश्यकता है तो यह DROP / CREATE को जोड़ती है।
रिपव्लन

10

यदि आपके प्रश्न का छिपा उद्देश्य एक बड़ी तालिका DROPबनाने INSERTसे पहले सूचकांक में है , तो यह उपयोगी एक-लाइनर है:

DROP INDEX IF EXISTS [IndexName] ON [dbo].[TableName]

यह सिंटैक्स SQL ​​सर्वर 2016 के बाद से उपलब्ध है। इसके लिए दस्तावेज़ IF EXISTS:

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

यदि आप इसके बजाय प्राइमरी कुंजी से निपटते हैं, तो इसका उपयोग करें:

ALTER TABLE [TableName] DROP CONSTRAINT IF EXISTS [PK_name] 

7

नीचे फ़ंक्शन लिखा है जो मुझे यह देखने के लिए जल्दी से जांचने की अनुमति देता है कि क्या कोई सूचकांक मौजूद है; OBJECT_ID की तरह ही काम करता है।

CREATE FUNCTION INDEX_OBJECT_ID (
    @tableName VARCHAR(128),
    @indexName VARCHAR(128)
    )
RETURNS INT
AS
BEGIN
    DECLARE @objectId INT

    SELECT @objectId = i.object_id
    FROM sys.indexes i
    WHERE i.object_id = OBJECT_ID(@tableName)
    AND i.name = @indexName

    RETURN @objectId
END
GO

संपादित करें: यह केवल तालिका का OBJECT_ID लौटाता है, लेकिन यदि सूचकांक मौजूद नहीं है तो यह पूर्ण होगा। मुझे लगता है कि आप इसे index_id पर वापस लाने के लिए सेट कर सकते हैं, लेकिन यह सुपर उपयोगी नहीं है।


1
-- Delete index if exists
IF EXISTS(SELECT TOP 1 1 FROM sys.indexes indexes INNER JOIN sys.objects 
objects ON indexes.object_id = objects.object_id WHERE indexes.name 
='Your_Index_Name' AND objects.name = 'Your_Table_Name')
BEGIN
    PRINT 'DROP INDEX [Your_Index_Name] ON [dbo].[Your_Table_Name]'
    DROP INDEX [our_Index_Name] ON [dbo].[Your_Table_Name]
END
GO

-1

जाँच करने के लिए क्लस्टर इंडेक्स विशेष टेबल पर मौजूद है या नहीं:

SELECT * FROM SYS.indexes 
WHERE index_id = 1 AND name IN (SELECT CONSTRAINT_NAME FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS WHERE TABLE_NAME = 'Table_Name')

5
यह प्राथमिक कुंजी और अद्वितीय बाधाओं को लौटाता है, लेकिन उनमें से कोई भी एक जरूरी सूचकांक नहीं है।
मार्क सोउल 9'13

index_id = 1 गलत है जहाँ खंड है। सूचकांक को एक अलग आईडी सौंपा जा सकता है
फजीबियर
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.