SSIS。使用 SQL 服务器的结果作为 Vertica 查询中的 where 子句

SSIS. Use results of SQL Server as a where clause in a Vertica Query

我在 SQL 服务器中有一个视图,它检测 table 中没有产品描述的所有产品 ID。 在 vertica 中,我们拥有所有产品 ID 及其描述。 我的想法是构建一个 SSIS 包,它可以提取所有缺少描述的产品 ID,并将其用作 Vertica 查询中的 where 子句。

我已经尝试过使用用户变量,但我失败了。我是 SSIS 初学者

这就是我要找的。

SELECT [Product ID], [Product Desc]
FROM VerticaTable
WHERE [Product ID] IN (@Variable?)

变量应该是这样的。

SELECT DISTINCT [Product ID] FROM SQLSerrverViewThatHasMissingDesc

基本上你有两种方法可以做到这一点。

首先,我想让您知道 SSIS 包中的 SELECT 不会向您显示任何内容,但您可以对查询进行更改,例如插入结果变成 table.

  1. 创建一个Object类型变量1并用Foreach Loop Container迭代该变量1,将每个值赋给另一个变量2(预先创建,可能是String类型多变的)。然后在容器中,将 Execute SQL task 与查询放在一起:

    SELECT [Product ID], [Product Desc]
    FROM VerticaTable
    WHERE [Product ID] = ?
    

    在参数映射页面中将变量 1 映射为 Index 0。 (如果您使用 OLE DB 作为连接类型)

    • 使用此方法的缺点是您无法同时查看所有产品ID,因为这是一个循环过程,除非您想将每个结果加载到table.
  2. 如果您希望同时查看所有候选结果,最常见的方法是使用 Dynamic SQL,因为查询中的任何地方都不支持变量。

因此,与您编写的查询相同,但需要一些 add-ups。

1)首先创建三个变量,variable1variable2variable3variable1Object类型,variable2variable3String 类型。

2) 接下来,您需要一个 Foreach Loop Container 来构建您的变量。在 Foreach Loop Container 中,拖放 Script Task。在容器之前,连接一个Execute SQL task,在容器之后,连接另一个Execute SQL task

所以物理顺序:执行SQL任务1->Foreach循环容器,里面:脚本任务->执行SQL任务2

3) 打开Execute SQL Task 1,将SELECT DISTINCT [Product ID] FROM SQLSerrverViewThatHasMissingDesc放入query,进入Result set页面,赋值Variable1

4) 移动到 Foreach loop Container,选择 Foreach ADO Enumerator,然后选择 Variable1 作为 ADO object source variable,模式为 Rows in the first table,然后转到 Variable mappings页,选择Variable2,默认索引

5) 进入Script task,打开它,选择Variable作为ReadOnlyVariable,在ReadWrite variable,选择Variable3,编辑脚本, 将以下代码粘贴到 Main()

    if (Dts.Variables["User::Variable3"].Value.ToString() == "")
    {
        Dts.Variables["User::Variable3"].Value = Dts.Variables["User::Variable2"].Value.ToString();
    }
    else
    {
        Dts.Variables["User::Variable3"].Value = Dts.Variables["User::Variable2"].Value.ToString() + "," + Dts.Variables["User::Variable2"].Value.ToString();
    }
    Dts.TaskResult = (int)ScriptResults.Success;

6) 在上述步骤之后,理想情况下,您的 Variable3 将有一个由 , 分隔的长字符串,如 A,B,C,D,E。您想要获取此字符串的原因是因为此 Variable3 稍后将在 Execute SQL task 中用作 Dynamic SQL

的一部分

7) 最后一步到了,在 Execute SQL Task 2 中,使用以下查询:

DECLARE @SQL VARCHAR(MAX)
SET @SQL = 'SELECT [Product ID], [Product Desc]
FROM VerticaTable
WHERE [Product ID] IN (''' + ? + ''')'

在参数映射中,选择Vareiable3,索引为0。

8) 执行包。

但是它不会显示任何东西,但是如果你尝试模拟SSMS中的动态过程,你会看到结果。

LONG 的回答很好。我将添加一些调整以获得您的 IN 子句。请接受他的回答,如果您觉得这对您有帮助,请点赞。

使用执行 SQL 任务直接在 SQL 服务器中使用填充函数获取 IN 子句,并将结果集直接放入字符串变量中。

合并仅处理 null(无结果)并将变量设置为空字符串。

declare @t table (ProdID int)

insert into @t
values(1),(1),(2),(3)

select  coalesce(
        stuff( 
                (select ','+cast(ProdID as varchar(5)) 
                from @t
                group by ProdID
                for XML path(''))
                ,1,1,'')
                ,'') as delimProdIds

结果:

delimProdIds
1,2,3

只需将@t 更改为您的视图

在控制流中(在这个 exec SQL 步骤之后)放置一个表达式,变量 !='' (Empty String) 如果是,它将在此处结束该过程。

龙创建变量的脚本有一点错误:

Dts.Variables["User::Variable3"].Value = 
    Dts.Variables["User::Variable2"].Value.ToString() + "," + 
    Dts.Variables["User::Variable2"].Value.ToString();

Variable3有值时,每次都用Variable2覆盖。大概应该是:

Dts.Variables["User::Variable3"].Value = 
    Dts.Variables["User::Variable3"].Value.ToString() + "," + 
    Dts.Variables["User::Variable2"].Value.ToString();