2011-11-22 95 views
5

我有一個超過130列的表(不要問 - 我沒有做到)。我們需要從該表中刪除每個空行(每個字段爲空),而不顯式列出每列。理想情況下,我希望使用動態SQL的解決方案可應用於任何表。我怎樣才能做到這一點?如何刪除任何SQL表中的每個空行

回答

3

這將讓你至少一部分的方式有:

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 

注意使用QUOTENAME辦理名字古怪的列。還要注意,假設所有列都是字符串列(或者可以隱式轉換爲字符串)。在您的解決方案中,您可能需要一些條件邏輯(使用CASE)來處理不同的數據類型,例如

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

我會考慮看看它包含有關您的表,列,鍵等信息INFORMATION_SCHEMA意見。使用TABLESCOLUMNS視圖可以讓你得到一個非常強大的解決方案。這裏是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

對於像這樣的事情,我傾向於使用可視化查詢構建器或設計器。它們會自動放入所有字段名稱,並且可以將IS NULL或=''複製並粘貼到每個字段的條件編輯中,並生成正確的查詢。在將它們構建並測試爲SELECT後,將它們轉換爲DELETE或任何其他需要的查詢類型。

2

這將刪除每列爲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 

結果:

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/

編輯:

如果你想刪除字符串字段以及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 
0

參數化的@Elias Hossain的答案在下面複製。

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