基于来自另一个数据库的查询结果查询数据库

fau*_*ong 9 sql sql-server ssis etl ssis-2012

我在VS 2013中使用SSIS.我需要从1个数据库中获取ID列表,并且使用该ID列表,我想查询另一个数据库,即SELECT ... from MySecondDB WHERE ID IN ({list of IDs from MyFirstDB}).

Had*_*adi 11

有3种方法可以实现这一目标:

第一种方法 - 使用查找转换

首先你必须添加Lookup Transformation像@TheEsisia这样的答案,但还有更多要求:

  • 在查找你要编写一个包含ID列表查询(例如:SELECT ID From MyFirstDB WHERE ...)

  • 至少你必须从查找表中选择一列

  • 这些不会过滤行,但这会从第二个表中添加值

要过滤行,WHERE ID IN ({list of IDs from MyFirstDB})您必须在查找错误输出中执行一些工作,Error case有两种方法:

在此输入图像描述

  1. 设置错误处理,Ignore Row以便添加的列(来自查找)值为空,因此您必须添加Conditional split具有等于​​NULL的值的过滤器行.

假设您已选择col1查找列,因此必须使用类似的表达式

ISNULL([col1]) == False
Run Code Online (Sandbox Code Playgroud)
  1. 或者您可以将错误处理设置为Redirect Row,因此所有行都将被发送到错误输出行,这可能不会被使用,因此将过滤数据

该方法的缺点是在执行期间加载和过滤所有数据.

此外,如果在加载所有数据后在本地计算机(服务器上的第二个方法)上进行网络过滤,那么就是内存.

第二种方法 - 使用脚本任务

为了避免加载所有数据,您可以执行一种解决方法,您可以使用脚本任务实现此目的:(在VB.NET中编写回答)

假设连接管理器名称是TestAdo并且"Select [ID] FROM dbo.MyTable"是获取id列表的查询,并且User::MyVariableList是要存储id列表的变量

注意:此代码将从连接管理器读取连接

    Public Sub Main()

        Dim lst As New Collections.Generic.List(Of String)


        Dim myADONETConnection As SqlClient.SqlConnection  
    myADONETConnection = _  
        DirectCast(Dts.Connections("TestAdo").AcquireConnection(Dts.Transaction), _  
        SqlClient.SqlConnection)

        If myADONETConnection.State = ConnectionState.Closed Then
        myADONETConnection.Open()
        End If

        Dim myADONETCommand As New SqlClient.SqlCommand("Select [ID] FROM dbo.MyTable", myADONETConnection)

        Dim dr As SqlClient.SqlDataReader

        dr = myADONETCommand.ExecuteReader

        While dr.Read

            lst.Add(dr(0).ToString)

        End While


        Dts.Variables.Item("User::MyVariableList").Value = "SELECT ... FROM ... WHERE ID IN(" &  String.Join(",", lst) & ")"

        Dts.TaskResult = ScriptResults.Success
    End Sub
Run Code Online (Sandbox Code Playgroud)

并且User::MyVariableList应该用作源(变量中的Sql命令)

第三种方法 - 使用Execute Sql Task

与第二种方法类似,但这将使用Execute SQL Task然后使用整个查询构建IN子句OLEDB Source,

  1. 只需在DataFlow任务之前添加一个执行SQL任务
  2. 设置ResultSet属性single
  3. 选择User::MyVariableList结果集
  4. 使用以下SQL命令

    DECLARE @str AS VARCHAR(4000)
    
    SET @str = ''
    
    SELECT @str = @str + CAST([ID] AS VARCHAR(255)) 
    FROM dbo.MyTable 
    
    SET @str = 'SELECT * FROM  MySecondDB WHERE ID IN (' + SUBSTRING(@str,1,LEN(@str) - 1) + ')'
    
    SELECT @str
    
    Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

在此输入图像描述

确保已将DataFlow Task Delay Validation属性设置为True


The*_*shi 5

这是一个经典的使用案例LookUp Transformation.首先,使用a OLE DB Source从第一个数据库中获取数据.然后,使用a LookUp Transformation根据ID第二个数据集中的值过滤此数据集.以下是使用以下步骤LookUp Transformation:

  1. General标签中,选择Full Cash,OLE DB Connection ManagerRedirect rows to no match output显示在下面的图片作为.请注意,使用Full Cash可为您的包提供出色的性能.

通用设置

在此输入图像描述

  1. Connection选项卡中,用于OLE DB Connection Manager连接到第二台服务器.然后,您可以直接选择带有ID值的数据集,或者(如下图所示)可以使用SQL代码从过滤数据集中选择ID.

连接:

在此输入图像描述

  1. 转到Columns选项卡并ID从两个数据集中选择列.对于第一个数据集中的每个记录,它将检查它ID是否在Available LookUp Column.如果是,它将转到Matching输出,否则No Matching输出.

匹配ID列:

在此输入图像描述

  1. 点击OK关闭LookUp.然后你需要选择LookUp Match Output.

匹配输出:

在此输入图像描述

  • 性能方面,在这种情况下不推荐查找,最好过滤OLEDB源的数据 (3认同)