在 SSIS 中,如何查找值的 ID,如果不匹配,则插入值和 return ID

In SSIS, How to lookup ID for value, if no match, insert value and return ID

使用 SSIS,我将分阶段提取加载到它的主数据库中。该过程的一部分是使用 LOOKUP 获取字符串值的 ID,如果它不存在,则将其插入引用 table(使用 OLE DB COMMAND)和 return 该 ID 通过关注了lookup.

LOOKUP 显示即使在插入后前 ~50 个值也不匹配。 有什么办法可以解决这个问题吗? 或者,我应该尝试另一种方法吗?

一些research/attempts...

  1. 最初,return没有匹配项。我不得不将所有查找更改为 "No Cache",这样它会重新加载引用 table(它们非常小,所以我怀疑我会遇到很大的性能问题)。

  2. 我看到的另一种方法是多播到不同的查找(基于我正在查找的列),并在我 inserted/looked 成功后将它们重新合并在一起。但据我所知,这种方法存在严重的性能问题。

我希望查找匹配或不匹配 match.If 不匹配,插入新值;然后,再次查找 ID 的值(如果不匹配,则失败)。合并原始匹配和原始不匹配进行下一次查找。

试试这个模式:

1.You are multicasting the dataset and grouping by just your lookup column
2.inserting your lookup and adding the scopeidentity(lookupid) to you grouped data
3.joining in the data you inserted to effective add your lookup value to every row
4.unioning your data back in

我不是很肯定,但您可能需要添加排序才能使用合并联接。

SSIS 数据流

Here is the final SSIS data flow model... 根据@KeithL 的建议,我在合并连接之前添加了排序。

脚本组件

using System;
using System.Data;
using System.Data.SqlClient;
using Microsoft.SqlServer.Dts.Pipeline.Wrapper;
using Microsoft.SqlServer.Dts.Runtime.Wrapper;

public class ScriptMain : UserComponent
{
    IDTSConnectionManager100 serverConMgr;

    public override void PreExecute()
    {
        base.PreExecute();
        serverConMgr = this.Connections.Connection;
    }
    public override void Input0_ProcessInputRow(Input0Buffer Row)
    {
        using (SqlConnection serverCon = new SqlConnection(serverConMgr.ConnectionString))
        {
            SqlCommand sql = new SqlCommand(
            "INSERT INTO DIM.CONTRIBUTOR (CONTRIBUTOR) VALUES ('" + Row.CONTRIBUTOR + "') " +
            "\n SELECT CAST(SCOPE_IDENTITY() AS INT) AS 'ID'"
            , serverCon);

            serverCon.Open();

            SqlDataReader data = sql.ExecuteReader();

            while (data.Read())
            {
                Row.CONTRIBUTORID = data.GetInt32(0);
            }

            data.Close();
        }
        
    }
}

“脚本组件”是最棘手的部分。它插入新值并检索相应的 ID。下面是该脚本的代码。

注意 3 件重要的事情...

  1. 数据库连接管理器(在本例中,名为“Connection”,必须是 ADO.Net 连接)
  2. Row.CONTRIBUTOR_ID 是我在脚本编辑器的“输入和输出”部分手动配置为输出的一行
  3. SqlDataReader 的“GetInt32()”方法不适用于 SCOPE_IDENTITY,除非 SCOPE_IDENTITY 在 sql 命令中显式转换为 int

这里有一些与脚本相关的其他注释...

  1. 你可以,但相当复杂
  2. 这是对 how to retrieve data using SqlDataReader
  3. 的 Microsoft 文档参考