Coś takiego:
SELECT
*
FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS
WHERE CONSTRAINT_NAME ='FK_TreeNodesBinaryAssets_BinaryAssets'
and TABLE_NAME = 'TreeNodesBinaryAssets'
ale dla indeksów.
Coś takiego:
SELECT
*
FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS
WHERE CONSTRAINT_NAME ='FK_TreeNodesBinaryAssets_BinaryAssets'
and TABLE_NAME = 'TreeNodesBinaryAssets'
ale dla indeksów.
Odpowiedzi:
Możesz to zrobić za pomocą prostego wyboru, takiego jak to:
SELECT *
FROM sys.indexes
WHERE name='YourIndexName' AND object_id = OBJECT_ID('Schema.YourTableName')
IF EXISTS(SELECT * ...) BEGIN ... END
.
YourTableName
powinno to być pełne imię i nazwisko ze schematem
W SQL 2008 i nowszych bardziej zwięzłą, kodową metodą wykrywania istnienia indeksu jest użycie INDEXPROPERTY
wbudowanej funkcji:
INDEXPROPERTY ( object_ID , index_or_statistics_name , property )
Najprostszym zastosowaniem jest IndexID
właściwość:
If IndexProperty(Object_Id('MyTable'), 'MyIndex', 'IndexID') Is Null
Jeśli indeks istnieje, powyższe zwróci jego identyfikator; jeśli nie, wróci NULL
.
AdaTheDEV, użyłem twojej składni i stworzyłem następujące i dlaczego.
Problem: Proces przebiega raz na kwadrans i zajmuje godzinę z powodu braku indeksu.
Korekta: Zmień proces zapytania lub Procedurę, aby sprawdzić indeks i utwórz go, jeśli go brakuje ... Na końcu zapytania i procedury usuwany jest ten sam kod, aby usunąć indeks, ponieważ nie jest on potrzebny, ale co kwartał. Pokazuje tutaj tylko składnię
-- 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
Nieznaczne odchylenie od pierwotnego pytania jednak mogą okazać się przydatne dla przyszłych osób lądujących tu chcących DROP
i CREATE
indeksu, czyli w skrypcie wdrażania.
Możesz pominąć istniejący czek, po prostu dodając następujące elementy do instrukcji create:
CREATE INDEX IX_IndexName
ON dbo.TableName
WITH (DROP_EXISTING = ON);
Przeczytaj więcej tutaj: UTWÓRZ INDEKS (Transact-SQL) - DROP_EXISTING Klauzula
Uwaga: Jak wspomniano w komentarzach, indeks musi już istnieć, aby ta klauzula działała bez zgłaszania błędu.
Jeśli ukrytym celem twojego pytania jest DROP
indeksowanie przed INSERT
przejściem do dużego stołu, to jest to przydatne w jednym wierszu:
DROP INDEX IF EXISTS [IndexName] ON [dbo].[TableName]
Ta składnia jest dostępna od SQL Server 2016. Dokumentacja dla IF EXISTS
:
Jeśli zamiast tego masz do czynienia z kluczem podstawowym, użyj tego:
ALTER TABLE [TableName] DROP CONSTRAINT IF EXISTS [PK_name]
Napisałem poniższą funkcję, która pozwala mi szybko sprawdzić, czy indeks istnieje; działa podobnie jak 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
EDYCJA: Zwraca tylko OBJECT_ID tabeli, ale będzie wynosić NULL, jeśli indeks nie istnieje. Przypuszczam, że możesz ustawić to tak, aby zwracało index_id, ale to nie jest bardzo przydatne.
-- 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
Aby sprawdzić Indeks klastrowy istnieje na konkretnej tabeli, czy nie:
SELECT * FROM SYS.indexes
WHERE index_id = 1 AND name IN (SELECT CONSTRAINT_NAME FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS WHERE TABLE_NAME = 'Table_Name')