2011-11-22 13 views
5

Tengo una tabla con más de 130 columnas (no preguntes, no lo hice). Necesitamos eliminar cada fila vacía (cada campo está vacío) de esta tabla sin enumerar explícitamente cada columna. Idealmente, me gustaría una solución que utiliza SQL dinámico y podría aplicarse a cualquier tabla. ¿Cómo puedo hacer esto?Cómo eliminar cada fila vacía de cualquier tabla SQL

Respuesta

3

Esto hará que los separe manera allí al menos:

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 

Nota el uso de QUOTENAME manejar columnas nombres extraños. También tenga en cuenta que esto supone que todas las columnas son columnas de cadena (o pueden convertirse implícitamente en una cadena). En su solución, es posible que desee cierta lógica condicional (usando CASE) para manejar diferentes tipos de datos, p.

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

yo consideraría echar un vistazo a las vistas INFORMATION_SCHEMA que contienen información sobre sus tablas, columnas, claves y similares. Usar las vistas TABLES y COLUMNS debería permitirle obtener una solución bastante sólida para esto. Aquí está el 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

Por ejemplo, tiendo a usar constructores de consultas visuales o diseñadores. Ponen automáticamente todos los nombres de campo y puede copiar y pegar IS NULL o = '' en una edición de condición para cada campo y produce la consulta correcta. Después de compilarlos y probarlos como SELECT, los convierto en DELETE o cualquier otro tipo de consulta que se necesite.

2

Esto eliminará las filas donde cada columna es 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 

Resultado:

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/

Editar:

Si desea eliminar campos cadena vacía, así como null que se vería así:

;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

Mod parametrico de la respuesta de @Elias Hossain copiado a continuación.

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 
Cuestiones relacionadas