2011-11-22 17 views
5

Tôi có một bảng có hơn 130 cột trong đó (đừng hỏi - tôi không tạo ra nó). Chúng ta cần loại bỏ mọi hàng trống (mỗi trường trống) từ bảng này mà không liệt kê rõ ràng từng cột. Lý tưởng nhất, tôi muốn một giải pháp sử dụng SQL động và có thể được áp dụng cho bất kỳ bảng nào. Tôi có thể làm cái này như thế nào?Cách xóa mọi hàng trống khỏi bất kỳ bảng SQL nào

Trả lời

3

Điều này sẽ giúp bạn có được một phần con đường đó ít nhất:

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 

Lưu ý việc sử dụng QUOTENAME để xử lý các cột tên kỳ quặc. Cũng lưu ý rằng điều này giả định tất cả các cột là cột chuỗi (hoặc có thể được chuyển đổi hoàn toàn thành chuỗi). Trong giải pháp của bạn, bạn có thể muốn một số logic có điều kiện (sử dụng CASE) để xử lý các kiểu dữ liệu khác nhau, ví dụ:

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

Tôi sẽ xem xét việc xem INFORMATION_SCHEMA chế độ xem chứa thông tin về bàn, cột, khóa và các loại tương tự. Sử dụng chế độ xem TABLESCOLUMNS sẽ cho phép bạn có được giải pháp khá mạnh mẽ cho điều này. Đây là 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

Đối với một điều như thế này, tôi có xu hướng sử dụng trình tạo hoặc trình thiết kế truy vấn trực quan. Chúng tự động đặt vào tất cả các tên trường và bạn có thể sao chép và dán IS NULL hoặc = '' vào một sửa đổi điều kiện cho mỗi trường và nó tạo ra truy vấn chính xác. Sau khi xây dựng và kiểm tra chúng như là một SELECT tôi chuyển đổi chúng thành DELETE hoặc bất kỳ loại truy vấn nào khác là cần thiết.

2

Điều này sẽ xóa các hàng có mỗi cột là 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 

Kết quả:

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:

Nếu bạn muốn loại bỏ lĩnh vực chuỗi rỗng cũng như null nó sẽ trông như thế này:

;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

Câu hỏi tham số được sao chép dưới đây.

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 
Các vấn đề liên quan