4

我有一个带有查找表的查找组件 a,该查找表返回varchar(4)具有 3 个可能值的列:“T”、“R”或“”(空字符串)。

我正在为查找表使用 OLE DB 连接,并尝试直接访问该表,并RTRIM()在列上指定一个查询,以确保该字符串为空而不是“一些空字符串”长度”。

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

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

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

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

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

4

2 回答 2

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 和空字符串行。

在此处输入图像描述

您可以看到,对于 5 个源行,T、R 和空字符串匹配并转到匹配输出路径。在我使用 NULL 或显式使用空格的地方,没有进行匹配。

如果我将查找模式从 Full Cache 更改为 Partial,则 NULL 继续不匹配,而显式空格匹配

呜?

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

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

要使您的完整缓存模式按预期工作,您需要RTRIM在源和/或查找转换中应用一个。如果您确信 RTRIM 无法使用您的源,请添加派生列转换,然后在此处应用您的 RTRIM,但我发现滥用数据库而不是 SSIS 更好。

比姆

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>
于 2014-11-03T19:55:07.343 回答
1

问题是 FULL Cache 使用 .Net 相等比较,而 Partial 和 None 使用 SQL。
我遇到了一个类似的问题,其中所有缓存都可以很好地与部分缓存一起使用,当我使用完整时,我会收到未找到行的错误,因为我在不匹配时失败。我的问题是源中的小写字符串和查找表中的大写版本,所以 Full/.Net 认为这些是不同的,Partial/SQL 很乐意进行不区分大小写的连接。如果您想查看失败的行,请将 No Match 行输出到 csv 文件。

于 2017-06-22T09:17:18.777 回答