SSIS多个未知列已更新

时间:2013-08-23 12:28:34

标签: sql sql-server sql-server-2005 ssis

我想知道是否有人遇到类似情况之前可以指出我正确的方向..?我要补充一点,因为有人用一个包含单词'NULL'的文本字符串替换了NULL值,这有点令人沮丧 - 我需要删除它。

我有6个非常大的表,超过250列以及每个超过100万条记录,我需要更新一行中出现单词NULL的列,并用适当的NULL值替换它 - 问题是我不知道它出现在哪一列。

首先,我有一些代码会列出每个列的值以及任何看起来计数低于预期的值,我将运行SQL查询以确定列是否包含字符串'NULL'并使用以下代码,将其替换为NULL。

declare @tablename sysname
declare @ColName nvarchar(500)
declare @sql nvarchar(1000)
declare @sqlUpdate nvarchar(1000)
declare @ParmDefinition nvarchar(1000)

set @tablename = N'Table_Name'  
Set @ColName = N'Column_Name'
set @ParmDefinition = N'@ColName nvarchar OUTPUT';

set @sql= 'Select ' + @ColName + ', Count(' + @ColName + ') from ' + @tablename + ' group by ' + @ColName + ''
Set @sqlUpdate = 'Update ' + @tablename + ' SET ' + @ColName + ' = NULL WHERE '+ @ColName + ' = ''NULL'''

print @sql
print @sqlUpdate 

EXECUTE sp_executesql @sql, @ParmDefinition, @ColName=@ColName OUTPUT;
EXECUTE sp_executesql @sqlUpdate, @ParmDefinition, @ColName=@ColName OUTPUT;

我正在尝试使用SSIS来迭代每一列,

Select Column_Name from Table_Name where Column_Name = 'NULL'

运行相应的查询,然后执行更新。

到目前为止,我可以从 Information.Schema 中提取列名,并从相应的表中获取记录计数,但是在运行实际的UPDATE语句时(如上所述,sqlUpdate) ) - 似乎没有一个组件对查询的动态措辞感到满意。

如果有记录(可能不正确),我正在使用条件分割来确定去哪里,并且我已尝试 OLE DB命令进行更新

简而言之,我想知道SSIS是否是这项工作的最佳工具,或者我是否在寻找错误的地方!

我正在使用SSIS 2005,这可能有我尚未意识到的限制!

任何指导都将不胜感激。

谢谢,

乔恩

2 个答案:

答案 0 :(得分:3)

原理基本上是合理的,但是我会把SSIS放在外面,用SSMS直接对着SQL Server做,并在那里构建循环逻辑,可能是用光标。

我不确定您是否需要先检查潜在值的计数 - 您可能也应用更新并接受有时它不会更新任何行 - 然后过滤将不会重复。

这样的东西
declare columns cursor local read_only for
select 
    c.TABLE_CATALOG,
    c.TABLE_SCHEMA,
    c.TABLE_NAME,
    c.COLUMN_NAME
from INFORMATION_SCHEMA.COLUMNS c
    inner join INFORMATION_SCHEMA.TABLES t
        on c.TABLE_CATALOG = t.TABLE_CATALOG
        and c.TABLE_SCHEMA = t.TABLE_SCHEMA
        and c.TABLE_NAME = c.TABLE_NAME
where c.DATA_TYPE like '%varchar%'  

open columns    
declare @catalog varchar(100), @schema varchar(100), @table varchar(100), @column varchar(100)

fetch from columns into @catalog, @schema, @table, @column

while @@FETCH_STATUS= 0
begin
     -- construct update here and execute it.       
    select @catalog, @schema, @table, @column
    fetch next from columns into @catalog, @schema, @table, @column
end

close columns
deallocate columns

您也可以考虑在一次点击中对表格应用所有更新,删除过滤器并根据不良数据的密度使用nullif

例如:

 update table
 set
    col1 = nullif(col1, 'null'),
    col2 = nullif(col2, 'null'),
    ...

答案 1 :(得分:1)

SSIS不是您的最佳选择。从概念上讲,您正在执行更新,大量更新。 SSIS可以真正快速插入。更新,通过痛苦的行基础连续发射。

在基于SQL的方法中,您将启动1000个更新语句来修复所有内容。在基于SSIS的方案中,使用带有OLE DB命令的数据流,您正在查看1000 * 1000000。

我会自己跳过光标。这是一个可以接受的时间来使用游标,但如果你的表像听起来那样充满了'NULL',那么假设你正在更新每一行并修复给定记录中的所有字段而不是回到同一行每件事都需要修复。