2013-01-31 22 views

Odpowiedz

9

Nie ma specjalnej procedury wewnątrz SQL Server, aby ten determinacji. Musisz zapytać o każdą tabelę. Oto brute force rozwiązanie:

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 

Jeden dziwactwo w powyższym roztworze jest to, że zostaną zwrócone dowolnej kolumny z tabeli, która jest pusta. Jeśli chcesz wykluczyć tabele, które są puste, wystarczy dostosować zapytanie do następującego:

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 
           )'; 
+0

Bardzo przydatne przy dopasowywaniu bazy danych (mam dużo nieużywanych kolumn, które powinienem upuścić: S). Właśnie dodałem typ danych i Kolejność do ostatniego SELECT. Dzięki! – Roimer

+0

„text Argument typ danych jest nieprawidłowy dla argumentu 1 funkcji len” pojawia się, gdy uruchomiony powyższy kod. Czy lepiej zamiast tego użyć ** DATALENGTH **? –

+0

@adolfgarlic - Można również użyć 'DataLength' funkcję. Podejrzewam, że funkcja Len może być barfingiem na typatach "text" i "ntext". – Thomas

Powiązane problemy