Что-то вроде этого:
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
NB. Как уже упоминалось в комментариях, индекс должен уже существовать, чтобы это предложение работало без ошибки.
Если скрытая цель вашего вопроса состоит в 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
РЕДАКТИРОВАТЬ: Это просто возвращает 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')