有 3 种方法可以实现此目的:
第一种方法 - 使用查找转换
首先你必须添加一个Lookup Transformation
就像@TheEsisia 回答的那样,但还有更多要求:
过滤行WHERE ID IN ({list of IDs from MyFirstDB})
你必须在查找错误输出中做一些工作Error case
有两种方法:
- 将错误处理设置为
Ignore Row
因此添加的列(来自查找)值将为 null ,因此您必须添加Conditional split
过滤具有等于 NULL 值的行。
假设你已经选择了col1
作为查找列,因此您必须使用类似的表达式
ISNULL([col1]) == False
- 或者您可以将错误处理设置为
Redirect Row
,因此所有行都会被发送到错误输出行,该行可能不会被使用,因此数据将被过滤
这种方法的缺点是所有数据在执行过程中都被加载和过滤。
此外,如果在所有数据加载到内存后在本地计算机上完成网络过滤(服务器上的第二种方法)。
第二种方法 - 使用脚本任务
为了避免加载所有数据,您可以采取一种解决方法,您可以使用脚本任务来实现此目的:(用VB.NET编写的答案)
假设连接管理器名称是TestAdo
and "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
And the User::MyVariableList
应该用作源(变量中的Sql命令)
第三种方法 - 使用执行 Sql 任务
与第二种方法类似,但这将使用Execute SQL Task
然后将整个查询用作OLEDB Source
,
- 只需在 DataFlow 任务之前添加一个执行 SQL 任务即可
- Set
ResultSet
财产给single
- Select
User::MyVariableList
作为结果集
-
使用以下 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
如果列具有字符串数据类型,您应该在值之前和之后添加引号,如下所示:
SELECT @str = @str + '''' + CAST([ID] AS VARCHAR(255)) + ''','
FROM dbo.MyTable
确保您已设置DataFlow Task
Delay Validation
财产给True