如何找出数据库中未使用的列(SQL Server 2008)。

时间:2021-11-05 08:29:16

columns that are left as blank/null/space or zero (given a list of tables).

保留为空白/空/空格或零的列(给定表列表)。

Assuming I can pull out table and column definitions from the central system tables, how should I check the above condition?

假设我可以从*系统表中提取表和列定义,我应该如何检查上述条件?

1 个解决方案

#1


9  

There is no special procedure inside of SQL Server to make this determination. You need to query each table. Here's a brute force solution:

SQL Server内部没有特殊的过程来进行此确定。您需要查询每个表。这是一个强力解决方案:

If object_id('tempdb..#Results') is not null
    Drop Table #Results;
GO
Create Table #Results
    (
    TableSchema sysname not null
    , TableName sysname not null
    , ColumnName sysname not null
    );
GO

Declare @TableSchema sysname;
Declare @TableName sysname;
Declare @ColumnName sysname;
Declare @DataType sysname;
Declare @Columns Cursor;
Declare @BaseSql nvarchar(max);
Declare @Sql nvarchar(max);
Declare @AdditionalFilter nvarchar(max);

Set @BaseSql = 'Insert #Results( TableSchema, TableName, ColumnName )
                Select ''TABLE_SCHEMA'', ''TABLE_NAME'', ''COLUMN_NAME''
                From ( Select 1 As V ) As Z
                Where Not Exists    (
                                    Select 1
                                    From [TABLE_SCHEMA].[TABLE_NAME]
                                    Where [COLUMN_NAME] Is Not Null
                                        ADDITIONAL_FILTER
                                    )';

Set @Columns = Cursor Fast_Forward For
    Select C.TABLE_SCHEMA, C.TABLE_NAME, C.COLUMN_NAME, C.DATA_TYPE
    From INFORMATION_SCHEMA.COLUMNS As C
        Left Join INFORMATION_SCHEMA.VIEWS As V
            On V.TABLE_SCHEMA = C.TABLE_SCHEMA
                And V.TABLE_NAME = C.TABLE_NAME
    Where V.TABLE_NAME Is Null;

Open @Columns;
Fetch Next From @Columns Into @TableSchema, @TableName, @ColumnName, @DataType;

While @@Fetch_Status = 0
Begin
    If @DataType In('int','smallint','tinyint','bigint','numeric','bit','decimal','money','smallmoney','float','real')
        Set @AdditionalFilter = 'And [COLUMN_NAME] <> 0';
    Else If @DataType In('char','nchar','varchar','nvarchar','text','ntext')
        Set @AdditionalFilter = 'And Len([COLUMN_NAME]) > 0';
    Else
        Set @AdditionalFilter = '';

    Set @Sql = Replace(@BaseSql, 'ADDITIONAL_FILTER', @AdditionalFilter);
    Set @Sql = Replace(@Sql, 'TABLE_SCHEMA', @TableSchema);
    Set @Sql = Replace(@Sql, 'TABLE_NAME', @TableName);
    Set @Sql = Replace(@Sql, 'COLUMN_NAME', @ColumnName);

    --Print @Sql
    Exec(@Sql)
    Fetch Next From @Columns Into @TableSchema, @TableName, @ColumnName, @DataType;
End

Close @Columns;
Deallocate @Columns;

Select *
From #Results

One quirk in the above solution is that any column from a table that is empty will be returned. If you wanted to exclude tables that are empty, you need only adjust the query to the following:

上述解决方案中的一个怪癖是将返回表中为空的任何列。如果要排除空表,则只需将查询调整为以下内容:

Set @BaseSql = 'Insert #Results( TableSchema, TableName, ColumnName )
                Select ''TABLE_SCHEMA'', ''TABLE_NAME'', ''COLUMN_NAME''
                From ( Select 1 As V ) As Z
                Where Exists    (
                                Select 1
                                From [TABLE_SCHEMA].[TABLE_NAME]
                                )
                And Not Exists  (
                                Select 1
                                From [TABLE_SCHEMA].[TABLE_NAME]
                                Where [COLUMN_NAME] Is Not Null
                                    ADDITIONAL_FILTER
                                )';

#1


9  

There is no special procedure inside of SQL Server to make this determination. You need to query each table. Here's a brute force solution:

SQL Server内部没有特殊的过程来进行此确定。您需要查询每个表。这是一个强力解决方案:

If object_id('tempdb..#Results') is not null
    Drop Table #Results;
GO
Create Table #Results
    (
    TableSchema sysname not null
    , TableName sysname not null
    , ColumnName sysname not null
    );
GO

Declare @TableSchema sysname;
Declare @TableName sysname;
Declare @ColumnName sysname;
Declare @DataType sysname;
Declare @Columns Cursor;
Declare @BaseSql nvarchar(max);
Declare @Sql nvarchar(max);
Declare @AdditionalFilter nvarchar(max);

Set @BaseSql = 'Insert #Results( TableSchema, TableName, ColumnName )
                Select ''TABLE_SCHEMA'', ''TABLE_NAME'', ''COLUMN_NAME''
                From ( Select 1 As V ) As Z
                Where Not Exists    (
                                    Select 1
                                    From [TABLE_SCHEMA].[TABLE_NAME]
                                    Where [COLUMN_NAME] Is Not Null
                                        ADDITIONAL_FILTER
                                    )';

Set @Columns = Cursor Fast_Forward For
    Select C.TABLE_SCHEMA, C.TABLE_NAME, C.COLUMN_NAME, C.DATA_TYPE
    From INFORMATION_SCHEMA.COLUMNS As C
        Left Join INFORMATION_SCHEMA.VIEWS As V
            On V.TABLE_SCHEMA = C.TABLE_SCHEMA
                And V.TABLE_NAME = C.TABLE_NAME
    Where V.TABLE_NAME Is Null;

Open @Columns;
Fetch Next From @Columns Into @TableSchema, @TableName, @ColumnName, @DataType;

While @@Fetch_Status = 0
Begin
    If @DataType In('int','smallint','tinyint','bigint','numeric','bit','decimal','money','smallmoney','float','real')
        Set @AdditionalFilter = 'And [COLUMN_NAME] <> 0';
    Else If @DataType In('char','nchar','varchar','nvarchar','text','ntext')
        Set @AdditionalFilter = 'And Len([COLUMN_NAME]) > 0';
    Else
        Set @AdditionalFilter = '';

    Set @Sql = Replace(@BaseSql, 'ADDITIONAL_FILTER', @AdditionalFilter);
    Set @Sql = Replace(@Sql, 'TABLE_SCHEMA', @TableSchema);
    Set @Sql = Replace(@Sql, 'TABLE_NAME', @TableName);
    Set @Sql = Replace(@Sql, 'COLUMN_NAME', @ColumnName);

    --Print @Sql
    Exec(@Sql)
    Fetch Next From @Columns Into @TableSchema, @TableName, @ColumnName, @DataType;
End

Close @Columns;
Deallocate @Columns;

Select *
From #Results

One quirk in the above solution is that any column from a table that is empty will be returned. If you wanted to exclude tables that are empty, you need only adjust the query to the following:

上述解决方案中的一个怪癖是将返回表中为空的任何列。如果要排除空表,则只需将查询调整为以下内容:

Set @BaseSql = 'Insert #Results( TableSchema, TableName, ColumnName )
                Select ''TABLE_SCHEMA'', ''TABLE_NAME'', ''COLUMN_NAME''
                From ( Select 1 As V ) As Z
                Where Exists    (
                                Select 1
                                From [TABLE_SCHEMA].[TABLE_NAME]
                                )
                And Not Exists  (
                                Select 1
                                From [TABLE_SCHEMA].[TABLE_NAME]
                                Where [COLUMN_NAME] Is Not Null
                                    ADDITIONAL_FILTER
                                )';