0

我想知道在此之前是否有人遇到过类似的情况可以为我指明正确的方向..?我要补充一点,这有点令人沮丧,因为有人用包含单词“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,它可能有一些我还不知道的限制!

任何指导将不胜感激。

谢谢,

乔恩

4

2 回答 2

3

原则基本上是合理的,但我会忽略 SSIS,并直接针对 SQL Server 使用 SSMS 并在那里构建循环逻辑,可能使用游标。

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

就像是

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'),
    ...
于 2013-08-23T12:33:17.780 回答
1

SSIS 不会是您的最佳选择。从概念上讲,您正在执行更新,很多更新。SSIS 可以进行非常快速的插入。更新,是通过痛苦的行来连续触发的。

在基于 SQL 的方法中,您将触发 1000 条更新语句来修复所有问题。在基于 SSIS 的场景中,使用带有 OLE DB 命令的数据流,您正在查看 1000 * 1000000。

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

于 2013-08-23T12:45:24.227 回答