使用完全缓存时,查找组件无法匹配空字符串

时间:2014-11-03 17:51:21

标签: sql-server ssis etl ssis-2012

我在查找组件a中有一个查找表,该查找表使用3个可能的值重新调整varchar(4)列:" T"," R"或"" (空字符串)。

我使用OLE DB连接查找表,并尝试直接访问该表,并在列上指定RTRIM()的查询,以确保该字符串是空的,而不是长度为#34;的空白字符串。

如果我将缓存模式设置为" Partial cache"一切正常(直接读取表或使用修剪查询),输入表的空字符串正确匹配相应的查找表行。

但是,如果我将缓存模式更改为"完全缓存",则根本没有匹配任何空字符串。

我已检查数据类型DT_STR和长度4在查找表和输入表中是否相同。

有什么能解释这种行为吗?可以修改吗?

注意:这不是空值的文档问题。这是关于空字符串的。

2 个答案:

答案 0 :(得分:3)

在某处,您在源代码或查找中都有尾随空格。

考虑以下源查询。

SELECT
    D.SourceColumn
,   D.Description
FROM
(
    VALUES 
        (CAST('T' AS varchar(4)), 'T')
    ,   (CAST('R' AS varchar(4)), 'R')
    ,   (CAST('' AS varchar(4)), 'Empty string')
    ,   (CAST('    ' AS varchar(4)), 'Blanks')
    ,   (NULL, 'NULL')
) D (SourceColumn, Description);

对于我的查找,我将上述查询限制为仅T,R和空字符串行。

enter image description here

您可以看到,对于5个源行,T,R和Empty String匹配并转到Match Output路径。在我使用NULL或显式使用空格的地方,进行了匹配。

如果我将查找模式从“完全缓存”更改为“部分”,则在显式空格 匹配时,NULL将继续不匹配。

WUT?

在完全缓存模式下,Lookup转换执行源查询并在SSIS正在执行的机器上本地保存数据。使用.NET相等规则,此查找将完全匹配。在这种情况下,''将与' '不匹配。

但是,当我们将缓存模式更改为“无”或“部分”时,我们将不再依赖.NET匹配规则,而是使用源数据库的匹配规则。在TSQL中,'' 匹配' '

要使完全缓存模式按预期工作,您需要在源和/或查找转换中应用RTRIM。如果您确信RTRIM没有使用您的源代码,请添加派生列转换,然后在那里应用您的RTRIM,但我发现滥用数据库而不是SSIS会更好。

BIML

商业智能标记语言Biml描述了商业智能平台。 BIDS Helper,是Visual Studio / BIDS / SSDT的免费补充,我们将使用它将下面的Biml文件转换为SSIS包。

以下biml将生成

<Biml xmlns="http://schemas.varigence.com/biml.xsd">
    <Connections>
        <OleDbConnection Name="CM_OLE" ConnectionString="Data Source=localhost\dev2012;Initial Catalog=tempdb;Provider=SQLNCLI11.0;Integrated Security=SSPI;" />
    </Connections>
    <Packages>
        <Package ConstraintMode="Linear" Name="so_26719974">
            <Tasks>
                <Dataflow Name="DFT Demo">
                    <Transformations>
                        <OleDbSource 
                            ConnectionName="CM_OLE" 
                            Name="OLESRC Source">
                            <DirectInput>
                            SELECT
                                D.SourceColumn
                            ,   D.Description
                            FROM
                            (
                                VALUES 
                                    (CAST('T' AS varchar(4)), 'T')
                                ,   (CAST('R' AS varchar(4)), 'R')
                                ,   (CAST('' AS varchar(4)), 'Empty string')
                                ,   (CAST('    ' AS varchar(4)), 'Blanks')
                                ,   (NULL, 'NULL')
                            ) D (SourceColumn, Description);
                            </DirectInput>
                        </OleDbSource>
                        <Lookup 
                            Name="LKP POC"
                            OleDbConnectionName="CM_OLE"
                            NoMatchBehavior="RedirectRowsToNoMatchOutput"
                            >
                            <DirectInput>
                            SELECT
                                D.SourceColumn
                            FROM
                            (
                                VALUES 
                                    (CAST('T' AS varchar(4)))
                                ,   (CAST('R' AS varchar(4)))
                                ,   (CAST('' AS varchar(4)))
                            ) D (SourceColumn);
                            </DirectInput>
                            <Inputs>
                                <Column SourceColumn="SourceColumn" TargetColumn="SourceColumn"></Column>
                            </Inputs>
                        </Lookup>
                        <DerivedColumns Name="DER Default catcher" />
                        <DerivedColumns Name="DER NoMatch catcher">
                            <InputPath OutputPathName="LKP POC.NoMatch" />
                        </DerivedColumns>
                    </Transformations>

                </Dataflow>
            </Tasks>
        </Package>
    </Packages>
</Biml>

答案 1 :(得分:1)

问题是FULL Cache使用.Net相等比较而Partial和None使用SQL 我有一个类似的问题,一切都适用于部分缓存,当我使用完全时,我得到错误的行未找到,因为我没有匹配失败。 我的问题是源代码中的小写字符串和Lookup表中的UPPER版本,因此Full / .Net将这些视为不同,而Partial / SQL很乐意进行不区分大小写的连接。 如果要查看失败的行,请将“无匹配”行输出到csv文件。