Как проверить, существует ли определенный индекс в таблице?


что-то вроде этого:

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

, но и для индексов.

6   231   2010-04-22 13:55:15

6 ответов:

вы можете сделать это с помощью прямого выбора такой:

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

AdaTheDEV, я использовал ваш синтаксис и создал следующее И почему.

проблема: процесс выполняется один раз в четверть часа из-за отсутствия индекса.

исправление: изменить процесс запроса или процедуру для проверки индекса и создать его, если он отсутствует... Тот же код помещается в конце запроса и процедуры для удаления индекса, так как он не нужен, Но ежеквартально. Здесь показан только синтаксис drop

-- 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

более лаконичный способ, кодирование-мудрый, чтобы обнаружить существование индекса следующим образом:

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

Если индекс существует, IndexProperty вернет идентификатор, если нет, то не будет.

небольшое отклонение от первоначального вопроса, однако, может оказаться полезным для будущих людей, приземляющихся здесь, желающих DROP и CREATE индекс, т. е. в скрипте развертывания.

вы можете обойти проверку exists, просто добавив следующее в инструкцию create:

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

подробнее здесь: CREATE INDEX (Transact-SQL) - Drop_existing предложение

N. B. Как уже упоминалось в комментариях, индекс должен уже существовать для этого пункта работать, не выдавая ошибки.

написал ниже функцию, которая позволяет мне быстро проверить, существует ли индекс; работает так же, как 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, но это не очень полезно.

чтобы проверить, существует ли кластеризованный индекс в конкретной таблице или нет:

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