参数化OLEDB源查询

问题描述 投票:12回答:3

我在SSIS中创建了一个ETL,我希望我的数据源是select * from table_name where id='Variable'。这个变量是我定义为User created变量的。

我不明白我的源查询如何与SSIS范围变量进行交互。

目前唯一的选择是

  • 变量表
  • SQL命令
  • 来自变量的SQL命令

我想要的是拥有一个带有变量作为参数的SQL语句

ssis bids
3个回答
24
投票

简单。选择SQL command作为数据访问模式。输入带有问号作为参数占位符的查询。然后单击Parameters按钮并将您的变量映射到Parameter0对话框中的Set Query Parameters

有关MSDN的更多信息。


10
投票

@ Edmund方法的另一种替代方法是在另一个变量上使用Expression来构建字符串。假设您已经定义了@ [User :: FirstName],那么您将创建另一个变量@ [User :: SourceQuery]。

在此变量的属性中,将EvaluateAsExpression设置为True,然后设置类似"SELECT FirstName, LastName, FROM Person.Person WHERE FirstName = '" + @[User::FirstName] +"'"的表达式双引号是必需的,因为我们正在构建SSIS字符串。

不应该谴责这种方法有两个重要原因。

高速缓存

这种方法将在SQL Server中使用基本相同查询的N个副本来扩展您的计划缓存。它第一次运行并且值为“Edmund”SQL Server将创建一个执行计划并保存它(因为构建它们可能很昂贵)。然后运行包,值为“Bill”。 SQL Server检查它是否有此计划。它没有,它只有一个给Edmund,因此它创建了另一个计划副本,这次硬编码给Bill。泡沫冲洗重复,并观察你的可用内存减少,直到它卸载一些计划。

通过使用参数方法,当计划提交到SQL Server时,它应该在内部创建计划的参数化版本,并假定所提供的所有参数将导致相同的成本计算执行。一般来说,这是理想的行为。

如果您的数据库针对临时工作负载进行了优化(默认设置为关闭),那么应该减少这一点,因为每个计划都将进行参数化。

SQL注入

构建自己的字符串会遇到另一个令人讨厌的问题,那就是你打开SQL注入攻击,或者至少可以获得运行时错误。它就像拥有“d'Artagnan”的价值一样简单。该单引号将导致您的查询失败,从而导致程序包失败。将值更改为“'; DROP TABLE Person.Person; - ”将导致极大的痛苦。

您可能认为安全引用一切都是微不足道的,但是在您查询的任何地方始终如一地实施它的努力超出了您的雇主所支付的费用。更是如此,因为提供了本机功能来做同样的事情。


1
投票

使用OLEDB连接管理器(在我的情况下使用SQL Server Native Client 11.0提供程序)时,您可以捕获如下错误:

无法从SQL命令中提取参数。提供程序可能无法帮助解析命令中的参数信息。在这种情况下,使用“来自变量的SQL命令”访问模式,其中整个SQL命令存储在变量中。

因此,您需要在OLEDB连接管理器属性中显式指定数据库名称。否则,SQL Server Native Client可以使用不同的数据库名称(例如,MSSQL Server中的master)。在某些情况下,您可以为查询中使用的每个数据库对象显式指定数据库名称,例如:

select Name
from MyDatabase.MySchema.MyTable
where id = ?
© www.soinside.com 2019 - 2024. All rights reserved.