2010-04-22 111 views

Respuesta

347

Puede hacerlo utilizando una recta hacia adelante seleccione la siguiente manera:

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

También puede ajustar la declaración en un 'SI EXISTS (SELECT * ...) BEGIN ... END'. – bounav

+21

Vale la pena mencionar que 'YourTableName' debe ser nombre completo con el esquema – Marek

+0

Utilicé su consulta sin la cláusula name = 'YourIndexName' y anoté el nombre de una restricción única en mi tabla de la columna de nombre devuelta por su consulta. Es como UNIQ _.... Me sale un error, no es una restricción. No se pudo eliminar la restricción. Ver errores previos. Cómo puedo solucionar esto ? – Steam

-1

Para comprobar índice agrupado existe en particular, el cuadro o no:

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

Esto devuelve claves primarias y restricciones únicas, pero ninguna de ellas es necesariamente un índice agrupado –

+0

index_id = 1 es incorrecto where cláusula. El índice puede tener asignada una identificación diferente – Fuzzybear

3

escribió el siguiente función que me permite rápidamente verifique si existe un índice; funciona igual que 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: Esto sólo devuelve el OBJECT_ID de la mesa, pero será NULL si el índice no existe. Supongo que podría configurar esto para devolver index_id, pero eso no es muy útil.

50

AdaTheDEV, utilicé su sintaxis y creé lo siguiente y por qué.

Problema: El proceso se ejecuta una vez por trimestre, tardando una hora debido a la falta de índice.

Corrección: Altere el proceso o procedimiento de consulta para verificar el índice y crearlo si falta ... Se coloca el mismo código al final de la consulta y el procedimiento para eliminar el índice ya que no es necesario sino trimestralmente. Mostrando solo gota sintaxis aquí

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

Un método más conciso, en cuanto a la codificación, para detectar la existencia del índice es el siguiente;

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

Si el índice existe, IndexProperty devolverá un Id, si no lo hace, no lo hará.

+1

Disponible solo desde [SQL Server 2008 y superior] (https://msdn.microsoft.com/en-us/library/ms187729.aspx?f=255&MSPPError=-2147217396). – Adi

+3

Esta respuesta es superior, ya que es más fácil integrarla en un script de mantenimiento. Una nota es que la última opción 'IndexID' es un comando, no una respuesta dependiente del objeto requerida. [IndexProperty - Microsoft Docs] (https://docs.microsoft.com/en-us/sql/t-sql/functions/indexproperty-transact-sql) –

9

Una ligera desviación de la pregunta original, sin embargo, puede ser útil para las personas que aterricen aquí que desean DROP y CREATE un índice, es decir, en una secuencia de comandos de implementación.

puede omitir la comprobación existe simplemente añadiendo lo siguiente a su sentencia de creación:

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

Lee más aquí: CREATE INDEX (Transact-SQL) - DROP_EXISTING Clause

N. B. Como se menciona en los comentarios, el índice ya debe existir para que esta cláusula funcione sin arrojar un error.

+5

En realidad ... ¡ten cuidado! ¡Esto fallará si el índice aún no existe! Al menos en SQL Server 2008. –

+0

... y aún falla en SQL 2016 – Magier

+1

Debería haber leído los comentarios antes de implementar – Rabin

0

Puede utilizar una UDF como:

IF (SELECT [dbo].[Index_Exists] (N'SchemaName', N'TableName', N'IndexName')) = 0 
BEGIN 
    -- Your script 
END 

Esta función asegurar que el índice se está refiriendo es el más adecuado, ya que pueden utilizar el mismo índice y/o nombre de tabla para diferentes esquemas:

CREATE FUNCTION [dbo].[Index_Exists] (@Schema_Name sysname, @Table_Name sysname, @Index_Name sysname) 
RETURNS bit 
WITH EXECUTE AS CALLER 
AS 
BEGIN 
DECLARE @Output bit 

SET @Schema_Name = ISNULL(@Schema_Name, N'dbo'); 

IF EXISTS (SELECT * 
      FROM sys.indexes ind 
      JOIN sys.index_columns ic ON ind.object_id = ic.object_id and ind.index_id = ic.index_id 
      JOIN sys.columns col ON ic.object_id = col.object_id and ic.column_id = col.column_id 
      JOIN sys.tables t ON ind.object_id = t.object_id 
      WHERE @Table_Name = t.[name] 
      AND  @Schema_Name = OBJECT_SCHEMA_NAME(t.[object_id]) 
      AND  @Index_Name = ind.[name] 
     ) SET @Output = CAST(1 as bit) 

RETURN ISNULL(@Output,CAST(0 as bit)) 
END 
Cuestiones relacionadas