我有一个 OLE DB 源,它有一些空值,它有 50 列,我正在尝试提取必须NULLs
到错误数据目标的行,我对条件拆分的表达式是
ISNULL([StudentName]) == TRUE
但这意味着我必须对我拥有的所有列重复它,我想知道是否有另一种方法来处理这个问题。特别是因为我有多个表要处理。谢谢
我有一个 OLE DB 源,它有一些空值,它有 50 列,我正在尝试提取必须NULLs
到错误数据目标的行,我对条件拆分的表达式是
ISNULL([StudentName]) == TRUE
但这意味着我必须对我拥有的所有列重复它,我想知道是否有另一种方法来处理这个问题。特别是因为我有多个表要处理。谢谢
信不信由你,自从你发布它以来,这一直让我感到困惑。
我还没有想出办法做到这一点 SSIS 但这里是使用脚本组件源的可能解决方案。这将找到与至少有一个空列的行关联的所有键。
DataTable dt = new DataTable();
string sql = "Enter your extract SQL here";
using(OleDbConnection conn = new OleDbConnection("Data Source=XXXXXXXXX;Initial Catalog=YYYYY;Provider=SQLNCLI11.1;Integrated Security=SSPI;Auto Translate=False;"))
{
using (OleDbCommand cmd = new OleDbCommand(sql,conn))
{
cmd.CommandType = CommandType.Text;
conn.Open();
dt.Load(cmd.ExecuteReader());
}
}
foreach (DataRow row in dt.Rows)
{
foreach (DataColumn col in dt.Columns)
{
if (row[col] == DBNull.Value)
{
Output0Buffer.AddRow();
Output0Buffer.NullRowKey = row.Field<int>(0); //This is the 0 based index of the key in the data
break;
}
}
}
我遇到的问题是尝试使用 Output0Buffer 数据类型中的列,这是在使用转换的脚本组件时必须使用的。我需要实际使用脚本组件源并将数据加载到数据表中才能访问 Columns 属性。
当然还有另一种方法,为什么不创建一个为您生成条件的脚本呢?
如果 50 列不在特定表中,只需创建一个包含您需要的所有列的 tmp 表( select ..... into #tmp from .... )
然后,生成条件。
declare @schema sysname = 'Purchasing'
declare @table sysname = 'PurchaseOrders'
;with cols as (
select convert(varchar(max), 'ISNULL(' + QUOTENAME(column_name) + ') == TRUE') as col, TABLE_SCHEMA, TABLE_NAME, ordinal_position
from INFORMATION_SCHEMA.COLUMNS
where TABLE_SCHEMA = @schema and TABLE_NAME = @table and ORDINAL_POSITION = 1
union all
select CONVERT (varchar(max) , cl.col + ' || ISNULL(' + QUOTENAME(column_name) + ') == TRUE') as col, c.TABLE_SCHEMA, c.TABLE_NAME, c.ordinal_position
from INFORMATION_SCHEMA.COLUMNS c
inner join cols cl on cl.TABLE_SCHEMA = c.TABLE_SCHEMA and cl.TABLE_NAME = c.TABLE_NAME and c.ORDINAL_POSITION = cl.ORDINAL_POSITION + 1
)
select '= ' + cols.col
from cols
where ORDINAL_POSITION = (select MAX(ordinal_position) from cols)
使用 WideWorldImporters 数据库,这将产生条件,删除不需要的内容。
= ISNULL([PurchaseOrderID]) == TRUE || ISNULL([SupplierID]) == TRUE || ISNULL([OrderDate]) == TRUE || ISNULL([DeliveryMethodID]) == TRUE || ISNULL([ContactPersonID]) == TRUE || ISNULL([ExpectedDeliveryDate]) == TRUE || ISNULL([SupplierReference]) == TRUE || ISNULL([IsOrderFinalized]) == TRUE || ISNULL([Comments]) == TRUE || ISNULL([InternalComments]) == TRUE || ISNULL([LastEditedBy]) == TRUE || ISNULL([LastEditedWhen]) == TRUE
但请注意,无论您选择哪种方法(我的方法或使用 Excel 生成条件),在 SSIS 中测试 50 列可能会增加巨大的过堆,尤其是在您有很多行的情况下。
更好的选择是在数据集中的每一行上放置一个标志,并过滤/重定向是否设置了“HasNullValues”。
最简单的解决方案(我不确定是否从性能角度推荐)是在 OLE DB 源中使用 SQL 命令,您应该在其中添加一个新列,该列是所有列的串联。然后,您应该在条件拆分中使用此列,而不是提及所有列。例如:
SELECT *, [Column1] + [Column2] + [Column3] as [CheckColumn]
FROM [Table]
It's not clear if you meant the data bad
when ALL
columns are NULL
or just ANY
column is NULL
.
If it is ALL
, then you can do this:
COALESCE(col1, col2, col3, .....) IS NULL
If it is 'ANY`, then you can do the following:
(col1 + col2 + col3 + .....) IS NULL
In BOTH
cases:
you will need to convert non-string columns (numeric, date, etc) to string via CONVERT(varchar(8000), col)
这是使用您已经形成的条件拆分的完全不同的解决方案:
ISNULL([StudentName])
您可以通过粘贴列列表在 Excel 中构建 OR 测试(我从数据流路径上的元数据中获取)。我通常使用这种技术来构建目标表。
粘贴到 excel 中并将列名放入 Col A。
将此公式输入 ColB:
="ISNULL("&A1&")||"
在 B2 中直接输入这个公式:
=B1&"ISNULL("&A2&")||"
这应该在 B2 中产生如下结果:
ISNULL(Col1)||ISNULL(Col2)||
现在将 B2 拖放到列表的底部(在您的情况下为 B50)。
B50 现在将保存有条件拆分的最终公式:
ISNULL(Col1)||ISNULL(Col2)||ISNULL(Col3)||ISNULL(Col4)||ISNULL(Col5)||ISNULL(Col6)||ISNULL(Col7)||ISNULL(Col8)||ISNULL(Col9)||ISNULL(Col10)||ISNULL(Col11)||ISNULL(Col12)||ISNULL(Col13)||ISNULL(Col14)||ISNULL(Col15)||ISNULL(Col16)||ISNULL(Col17)||ISNULL(Col18)||ISNULL(Col19)||ISNULL(Col20)||ISNULL(Col21)||ISNULL(Col22)||ISNULL(Col23)||ISNULL(Col24)||ISNULL(Col25)||ISNULL(Col26)||ISNULL(Col27)||ISNULL(Col28)||ISNULL(Col29)||ISNULL(Col30)||ISNULL(Col31)||ISNULL(Col32)||ISNULL(Col33)||ISNULL(Col34)||ISNULL(Col35)||ISNULL(Col36)||ISNULL(Col37)||ISNULL(Col38)||ISNULL(Col39)||ISNULL(Col40)||ISNULL(Col41)||ISNULL(Col42)||ISNULL(Col43)||ISNULL(Col44)||ISNULL(Col45)||ISNULL(Col46)||ISNULL(Col47)||ISNULL(Col48)||ISNULL(Col49)||ISNULL(Col50)||
只需删除最后的||。