删除SQL Server

时间:2017-11-30 13:44:47

标签: sql-server

我可以根据条件删除SQL Server中schema的所有索引吗?

我解释一下:我希望在schema XX中删除包含列类型为float的所有索引。

我在下面编写了这个脚本,但我不确定列类型的行:

If Exists (Select * 
           From sys.indexes 
           Where name = 'indexName' 
             And Object_Id = Object_Id('schema xx.TABLE_NAME')
             And Object_Id =Object_Id ('nchar', 'nvarchar'))
    Drop Index indexNameOn dbo.Table_Name;

谢谢

1 个答案:

答案 0 :(得分:2)

此查询将帮助您查找所有使用float数据类型的列的索引。

SELECT  i.[name] as IndexName,
        o.[name] as TableName
FROM sys.indexes i
INNER JOIN sys.objects o
    ON i.[object_id] = o.[object_id] AND o.[type] = 'U' --USER_TABLE
INNER JOIN sys.index_columns ic
    ON i.[object_id] = ic.[object_id]
INNER JOIN sys.columns c
    ON c.column_id = ic.column_id AND c.[object_id] = ic.[object_id]
INNER JOIN sys.types t
    ON  c.system_type_id = t.system_type_id AND t.[name] = 'float'

在MSDN上,您可以找到有关此表的所有信息。要自动DROP all并在所有DB中搜索,您需要使用动态SQL。

此查询仅适用于当前数据库,我们需要在每个非系统数据库中进行搜索。

DECLARE @query nvarchar(max) = N''

-- Create a table to store a results of a search
IF OBJECT_ID(N'tempdb..##search_index') IS NOT NULL DROP TABLE ##search_index
CREATE TABLE ##search_index (
    [db_name] sysname,
    [index_name] sysname,
    [schema_name] sysname,
    [table_name] sysname
)
-- here we get all DBs except system (master, tempdb etc.)
;WITH cte AS (
    SELECT  CONCAT(N'USE ',QUOTENAME([name]),';') as db,
            [name] as [db_name]
    FROM sys.databases      -- take all DBs
    WHERE database_id > 4   -- not system
)
-- prepare a query for each DB
SELECT @query = @query + db + CHAR(13) +
N'INSERT INTO ##search_index
SELECT  '''+ [db_name] + ''' as DB,
        i.[name] as IndexName,
        sch.[name] as SchemaName,
        o.[name] as TableName
FROM sys.indexes i
INNER JOIN sys.objects o
    ON i.[object_id] = o.[object_id] AND o.[type] = ''U'' -- USER_TABLE
INNER JOIN sys.schemas sch
    ON o.[schema_id] = sch.[schema_id]
INNER JOIN sys.index_columns ic
    ON i.[object_id] = ic.[object_id]
INNER JOIN sys.columns c
    ON c.column_id = ic.column_id AND c.[object_id] = ic.[object_id]
INNER JOIN sys.types t
    ON  c.system_type_id = t.system_type_id AND t.[name] = ''float'';' + CHAR(13) + CHAR(13)
FROM cte 

PRINT @query
-- execute query
EXEC(@query)

-- take a look at the results
SELECT *
FROM ##search_index

使用PRINT,您可以看到生成了什么查询。样本在这里:

USE [Test];
INSERT INTO ##search_index
SELECT  'Test' as DB,
        i.[name] as IndexName,
        sch.[name] as SchemaName,
        o.[name] as TableName
FROM sys.indexes i
INNER JOIN sys.objects o
    ON i.[object_id] = o.[object_id] AND o.[type] = 'U' -- USER_TABLE
INNER JOIN sys.schemas sch
    ON o.[schema_id] = sch.[schema_id]
INNER JOIN sys.index_columns ic
    ON i.[object_id] = ic.[object_id]
INNER JOIN sys.columns c
    ON c.column_id = ic.column_id AND c.[object_id] = ic.[object_id]
INNER JOIN sys.types t
    ON  c.system_type_id = t.system_type_id AND t.[name] = 'float';

USE [Another One];
INSERT INTO ##search_index
SELECT  'Another One' as DB,
...

输出如下:

db_name         index_name  schema_name     table_name
Test            PK_Period   dbo             Periods
Another Test    PK_Test     dbo             Test

然后,如果您需要删除此索引,则需要检查。如果您对此有所了解,可以使用:

DECLARE @query_to_drop nvarchar(max) = N''

SELECT @query_to_drop = @query_to_drop + N'USE ' + QUOTENAME([db_name]) +'; DROP INDEX ' + QUOTENAME([index_name]) + ' ON ' + QUOTENAME([schema_name]) +'.'+ QUOTENAME([table_name]) +';'+ CHAR(13)
FROM ##search_index

EXEC(@query_to_drop)

这将为您提供如下查询:

USE [Test]; DROP INDEX [PK_Period] ON [dbo].[Periods];
USE [Another Test]; DROP INDEX [PK_Test] ON [dbo].[Test];