我正在SSIS中创建一个ETL,其中我希望我的数据源是限制查询,例如select * from table_name where id='Variable'
。这个变量就是我定义为用户创建的变量。
我不明白我的源查询如何与SSIS范围的变量进行交互。
唯一存在的选项是
我想要的是拥有一个带有变量作为参数的SQL语句
答案 0 :(得分:23)
简单。选择SQL command
作为数据访问模式。输入带有问号作为参数占位符的查询。然后点击Parameters
按钮,将变量映射到Parameter0
对话框中的Set Query Parameters
:
有关详情,请参阅MSDN。
答案 1 :(得分: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注入攻击,或者至少可以获得运行时错误。它就像拥有“d'Artagnan”的价值一样简单。该单引号将导致您的查询失败,从而导致程序包失败。将值更改为“'; DROP TABLE Person.Person; - ”将导致极大的痛苦。
您可能认为安全引用所有内容都是微不足道的,但是在您查询的任何地方始终如一地实施它的努力超出了您的雇主所支付的费用。更是如此,因为提供了本机功能来做同样的事情。
答案 2 :(得分: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 = ?