如何从任何SQL表中删除每个空行

时间:2011-11-22 22:43:45

标签: sql sql-server

我有一张超过130列的表格(不要问 - 我没有成功)。我们需要从此表中删除每个空行(每个字段为空),而不显式列出每列。理想情况下,我想要一个使用动态SQL的解决方案,并且可以应用于任何表。我怎么能这样做?

6 个答案:

答案 0 :(得分: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

答案 1 :(得分: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

答案 2 :(得分:0)

我会考虑查看包含有关表,列,键等信息的INFORMATION_SCHEMA视图。使用TABLESCOLUMNS视图可以让您获得非常强大的解决方案。这是MSDN documentation

答案 3 :(得分: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 

答案 4 :(得分:0)

对于像这样的事情,我倾向于使用视觉查询构建器或设计器。它们会自动输入所有字段名称,您可以将IS NULL或=''复制并粘贴到每个字段的条件编辑中,并生成正确的查询。在构建并测试它们作为SELECT后,我将它们转换为DELETE或任何其他需要的查询类型。

答案 5 :(得分: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