我在SSIS中创建一个ETL,其中我希望我的数据源是一个受限的查询,比如select * from table_name where id='Variable'
。这个变量就是我定义的用户创建的变量。
我不明白如何让我的源查询与SSIS作用域变量交互。
目前唯一的选择是
我想要的是有一个以变量作为参数的SQL语句。
发布于 2013-08-17 19:19:22
很简单。选择SQL command
作为数据访问模式。输入带有问号的查询作为参数占位符。然后单击Parameters
按钮并将您的变量映射到Set Query Parameters
对话框中的Parameter0
:
有关MSDN的更多信息可供查阅。
发布于 2013-08-18 15:12:11
@Edmund方法的一个次要选择是在另一个变量上使用表达式来构建字符串。假设您已经定义了@User::FirstName,那么您将创建另一个变量@User::SourceQuery。
在此变量的属性中,将EvaluateAsExpression设置为True
,然后设置一个类似于"SELECT FirstName, LastName, FROM Person.Person WHERE FirstName = '" + @[User::FirstName] +"'"
的表达式--双引号是必需的,因为我们正在构建SSIS字符串。
这种做法不应该被恳求有两大原因。
缓存
这种方法将使您的计划缓存在SQL Server中膨胀,其中包含N个本质上相同查询的副本。当它第一次运行并且值为"Edmund“时,Server将创建一个执行计划并保存它(因为构建它们的代价可能很高)。然后运行包,其值为"Bill“。Server检查是否有此计划。它没有,它只有一个埃德蒙,所以它创造了另一个副本的计划,这一次硬编码比尔。泡沫-冲洗-重复和看着你的可用内存减少,直到它卸载一些计划。
通过使用参数方法,当计划提交到Server时,应该在内部创建计划的参数化版本,并假定所提供的所有参数将导致相同的成本执行。一般来说,这是我们所期望的行为。
如果您的数据库是针对临时工作负载(默认情况下是关闭设置)进行优化的,则应该减轻这种情况,因为每个计划都将被参数化。
SQL注入
构建自己的字符串会遇到另一个很大的麻烦,那就是您打开了自己面对SQL注入攻击的大门,或者至少可以获得运行时错误。它就像拥有“d‘’Artagnan”的值一样简单。单引号将导致查询失败,导致包失败。将值更改为“;DROP Person.Person;-”将导致极大的痛苦。
你可能会认为安全地引用所有东西是微不足道的,但是无论你在哪里都要始终如一地执行它的努力超出了你的雇主给你的报酬。更重要的是,由于提供了本机功能来做同样的事情。
发布于 2019-04-03 14:12:48
当使用OLEDB连接管理器(在我的示例中使用Server本机客户端11.0提供程序)时,您可以捕获如下错误:
不能从SQL命令中提取参数。提供程序可能无助于解析命令中的参数信息。在这种情况下,使用"SQL命令从变量“访问模式,其中整个SQL命令存储在一个变量中。
因此,您需要在OLEDB连接管理器属性中显式指定数据库名称。否则,Server本机客户端可以使用不同的数据库名称(例如,MSSQL中的主数据库)。在某些情况下,可以为查询中使用的每个数据库对象显式指定数据库名称,例如:
select Name
from MyDatabase.MySchema.MyTable
where id = ?
https://stackoverflow.com/questions/18288183
复制相似问题