2011-11-22 14 views
5

Mam tabelę z ponad 130 kolumnami w niej (nie pytaj - nie zrobiłem tego). Musimy usunąć wszystkie puste wiersze (każde pole jest puste) z tej tabeli bez jawnego wyświetlania każdej kolumny. Idealnie, chciałbym rozwiązanie, które używa dynamicznego SQL i może być stosowane do każdej tabeli. Jak mogę to zrobić?Jak usunąć każdy pusty wiersz z dowolnej tabeli SQL

Odpowiedz

3

To będzie Ci rozstać sposób istnieje co najmniej:

DECLARE @myTable VARCHAR(MAX) 

SET @MyTable = 'myTable' 
DECLARE @SQL VARCHAR(MAX) 
SELECT @SQL = COALESCE(@SQL + ' AND ','')+ '(' +quotename(COLUMN_NAME) + ' = '''' OR ' +quotename(COLUMN_NAME) + ' IS NULL)' 
FROM information_schema.columns 
WHERE table_NAME = @myTable 

SET @SQL = 'DELETE FROM ' + quotename(@myTable) + ' WHERE ' + @sql 
select @sql 

Uwaga wykorzystanie QUOTENAME obsłużyć dziwnie nazwanych kolumn. Zauważ również, że zakłada to, że wszystkie kolumny są kolumnami (lub mogą być niejawnie przekształcone w łańcuch). W twoim rozwiązaniu możesz potrzebować logiki warunkowej (używając CASE) do obsługi różnych typów danych, np.

SELECT @SQL = COALESCE(@SQL + ' AND ','')+ '(' +quotename(COLUMN_NAME) + ' = ' + CASE WHEN data_type = 'int' then '0' when data_type = 'varchar' then '''' else '''' end + ' OR ' +quotename(COLUMN_NAME) + ' IS NULL)' 
    FROM information_schema.columns 
    WHERE table_NAME = @myTable 
0

uważam przyjrzeniu się poglądami INFORMATION_SCHEMA które zawierają informacje na temat tabel, kolumn, kluczy itp. Używanie widoków TABLES i COLUMNS powinno pozwolić na uzyskanie całkiem niezłego rozwiązania tego problemu. Oto MSDN documentation.

0
DECLARE @SQL VARCHAR(MAX) 
SELECT @SQL = COALESCE(@SQL + ' AND ','') + 
    (CASE 
    WHEN UPPER(DATA_TYPE) = 'INT' THEN ('(' +quotename(COLUMN_NAME) + ' = 0 OR ' +quotename(COLUMN_NAME) + ' IS NULL)') 
    WHEN UPPER(DATA_TYPE) = 'VARCHAR' THEN ('(' +quotename(COLUMN_NAME) + ' = '''' OR ' +quotename(COLUMN_NAME) + ' IS NULL)') 
      -- More conditions are goes here 
      -- Cover all data type (DATA_TYPE) used at your target table, or you may cover all existing data types 
    ELSE '' 
    END) 
FROM INFORMATION_SCHEMA.COLUMNS 
WHERE table_NAME = @targetTable 
SET @SQL = 'DELETE FROM ' + QUOTENAME(@targetTable) + ' WHERE ' + @sql 
SELECT @SQL 
0

Do takich jednorazowych rzeczy jak to używam wizualnych budowniczych zapytań lub projektantów. Automatycznie wstawiają wszystkie nazwy pól i można kopiować i wklejać IS NULL lub = '' do edycji warunków dla każdego pola i generuje poprawne zapytanie. Po zbudowaniu i przetestowaniu ich jako SELECT zamieniam je na DELETE lub jakikolwiek inny rodzaj zapytania.

2

Spowoduje to usunięcie wierszy, w których każda kolumna jest null.

-- Sample table 
declare @T table 
(
    Col1 int, 
    Col2 datetime, 
    Col3 bit, 
    Col4 nvarchar(max) 
) 

-- Add sample data 
insert into @T values 
(null,  null, null, null), 
( 1,  null, null, null), 
(null, getdate(), null, null), 
(null,  null, 1, null), 
(null,  null, null, '') 

-- Delete rows where all column values are null 
;with C(XmlCol) as 
(
    select 
    (select T.* 
    for xml path('row'), type) 
    from @T as T 
) 
delete from C 
where C.XmlCol.exist('row/*') = 0 

Wynik:

Col1  Col2     Col3 Col4 
----------- ----------------------- ----- ---------- 
1   NULL     NULL NULL 
NULL  2011-11-23 14:09:42.770 NULL NULL 
NULL  NULL     1  NULL 
NULL  NULL     NULL 

http://data.stackexchange.com/stackoverflow/q/118893/

Edit:

Jeśli chcesz usunąć pustych pól ciągów jak null to będzie wyglądać następująco:

;with C(XmlCol) as 
(
    select 
    (select T.* 
    for xml path('row'), type) 
    from @T as T 
) 
delete from C 
where C.XmlCol.exist('row/*[. != ""]') = 0 
0

Sparametryzowany mod odpowiedzi @Elias Hossain skopiowanej poniżej.

create proc dbo.spDeleteRowsWhereAllColsAreNull 
    @Schema nvarchar(116), 
    @Table nvarchar(116) 
as 
begin 
    declare 
      @RetMsg nvarchar(max), 
      @CountRows int, 
      @ProcName nvarchar(255) = N'dbo.spDeleteRowsWhereAllColsAreNull', 
      @DynamicSql nvarchar(max) = N'', 
      @Schema_Table nvarchar(255) = @Schema + N'.' + @Table, 
      @Column nvarchar(116), 
      @Lb nchar(1) = char(13), 
      @Tab nchar(1) = char(9) 

-- Check if target exists, else escape proc 
    if exists(select * 
       from sys.tables 
       where [object_id] = object_id(@Schema_Table)) 
    begin 
     select @DynamicSql = 'delete from ' + @Schema_Table + N' where ' ; 

-- Get all columns for target table into @DynamicSql 
     select @DynamicSql += 
      @Tab + name+ N' is null and ' + @Lb 
     from sys.columns 
     where [object_id] = object_id(@Schema_Table) ; 

     set @DynamicSql = left(@DynamicSql, len(@DynamicSql) - 6) ; 
     -- print @DynamicSql ; 

     exec sp_executesql @DynamicSql ; 
     set @CountRows = @@rowcount ; 
     set @RetMsg = @ProcName + N' executed in current Database ' + db_name() + N' on table ' + @Schema_Table + N'. ' + convert(nvarchar, @CountRows) + N' row(s) deleted.' ; 

-- Print results & return success 
     print @RetMsg ; 
     return 0 ; 
    end 
    else 
    begin 
-- Raiserror & return failure 
     set @RetMsg = @Schema_Table + N' does not exist current Database ' + db_name() + N'. Execution FAILED!'; 
     raiserror(@RetMsg, 11, -1) ; 
     return -1 ; 
    end ; 

end ; 
go 
Powiązane problemy