Щось на зразок цього:
SELECT
*
FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS
WHERE CONSTRAINT_NAME ='FK_TreeNodesBinaryAssets_BinaryAssets'
and TABLE_NAME = 'TreeNodesBinaryAssets'
але для індексів.
Щось на зразок цього:
SELECT
*
FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS
WHERE CONSTRAINT_NAME ='FK_TreeNodesBinaryAssets_BinaryAssets'
and TABLE_NAME = 'TreeNodesBinaryAssets'
але для індексів.
Відповіді:
Ви можете зробити це за допомогою прямого переднього вибору:
SELECT *
FROM sys.indexes
WHERE name='YourIndexName' AND object_id = OBJECT_ID('Schema.YourTableName')
IF EXISTS(SELECT * ...) BEGIN ... END
.
YourTableName
має бути повне ім’я зі схемою
Для SQL 2008 та новіших версій більш стислий метод кодування для виявлення існування індексу - за допомогою INDEXPROPERTY
вбудованої функції:
INDEXPROPERTY ( object_ID , index_or_statistics_name , property )
Найпростіше використання - це IndexID
властивість:
If IndexProperty(Object_Id('MyTable'), 'MyIndex', 'IndexID') Is Null
Якщо індекс існує, вищевказаний поверне свій ідентифікатор; якщо цього не відбудеться, він повернеться NULL
.
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
Невелике відхилення від початкового питання, однак, може виявитися корисним для майбутніх людей, які приземляються сюди, бажаючі DROP
та CREATE
індексувати, тобто в сценарії розгортання.
Ви можете обійти існуючий чек, просто додавши в заяву create таке:
CREATE INDEX IX_IndexName
ON dbo.TableName
WITH (DROP_EXISTING = ON);
Детальніше читайте тут: CREATE INDEX (Transact-SQL) - пункт DROP_EXISTING
Примітка. Як зазначалося в коментарях, індекс повинен вже існувати, щоб ця стаття працювала без помилки.
Якщо прихована мета вашого питання полягає DROP
в індексуванні перед тим, як зробити INSERT
велику таблицю, тоді це корисно однолінійним:
DROP INDEX IF EXISTS [IndexName] ON [dbo].[TableName]
Цей синтаксис доступний з SQL Server 2016. Документація для IF EXISTS
:
Якщо ви замість цього використовуєте праймер-ключ, використовуйте це:
ALTER TABLE [TableName] DROP CONSTRAINT IF EXISTS [PK_name]
Написав нижче функцію, яка дозволяє мені швидко перевірити, чи існує індекс; працює так само, як 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
EDIT: Це просто повертає OBJECT_ID таблиці, але це буде NULL, якщо індекс не існує. Я думаю, ви можете встановити це для повернення index_id, але це не дуже корисно.
-- 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
Щоб перевірити існування кластерного індексу на певній таблиці чи ні:
SELECT * FROM SYS.indexes
WHERE index_id = 1 AND name IN (SELECT CONSTRAINT_NAME FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS WHERE TABLE_NAME = 'Table_Name')