最佳实践:从变量"发送" SQL命令的存储过程在OLE DB源?

时间:2014-12-04 20:11:12

标签: sql sql-server stored-procedures ssis

在SSIS ETL中,我有一个查询,我需要在服务器/ db上运行,不允许我们创建存储过程。

我通常会将变量中的存储过程用作OLE DB源的源:

Usual method

但是,由于我们无法将存储过程放在此服务器上,因此我打算通过执行SQL语句将存储过程的代码存储到变量中,从我们的home数据库中检索文本,然后使用存储在此变量中的文本作为源的SQL命令:

New method

这样,我仍然可以远程更改SSIS OLE DB Source对象WHERE子句(只要我不改变SELECT部分)。

我无法想象这是非常常见的,所以我想得到一些意见 - 有更好的方法吗?我不想直接将此SP的所有代码放入OLE DB源代码编辑器中,因为我们无法在WHERE子句更新的情况下重新部署。

1 个答案:

答案 0 :(得分:2)

你已经得到了许多人不做的部分,并且使用Variables来推动你的包执行。你更进一步,因为你无法完全换掉你的专栏。为了迂腐,我是可以完全更改查询,只要呈现相同的元数据。

那么,这个问题就变成了如何最好地完成允许包具有由外力驱动的查询过滤器。考虑可维护性,易于调试等。

我的直觉反应是3变量

  • QueryBase:String。硬编码。 SELECT * FROM MyTable,当然我列举了我的专栏
  • 查询:字符串。 EvaluateAsExpression = True Expression:@ [User :: QueryBase] + @ [User :: QueryFilter]
  • QueryFilter:String

因此,我们在OLE DB Source中使用Query,就像在那里有更长的变量名一样。这种方法的唯一缺点是,在SSIS-2012之前是表达式中字符串长度的限制。这是... 4k我相信。如果你指定一个5k字符的值,那很好。它只是在表达式语言中,将两个字符串加在一起不能超过4k。

我没有指定QueryFilter将会包含哪些内容,也没有说明将它存在的魔力。那,我将基于您的环境,用法等的更大图景,但一般的概念是它最终会变成WHERE Condition1 IS NOT NULL但可能在完全重新加载的情况下,它变成一个空字符串。

那么,我们有什么选择来改变QueryFilter的值

  1. /SET是传递给调用进程(dtexec.exe)的可选参数,它使SSIS包运行。如果您的选择非常有限,并且不想构建其他基础设施以支持参数,那么只需编写一些示例。大约dtexec /file p1.dtsx /set \Package.Variables[User::QueryFilter].Properties[Value];" WHERE Condition1 IS NOT NULL"将它保存到.bat文件,不同的sql代理作业,等等。点击并运行即可完成。
  2. 配置方法。 SSIS提供本机功能,可以使用从2005年的SQL Server表,XML,注册表,父包和环境变量到当前版本的配置。这种方法的唯一缺点是它不支持使用不同参数的并发执行,如第一种。
  3. 环境方法。 2012年和2014年,通过新的项目部署模型,为我们提供了SSISDB目录中的环境概念,类似于使用SQL Server表进行配置,但是在开发完成并部署包之后完成。它相当不错,因为它构建了一个使用的值的历史记录,所以如果有人问为什么数据都错了,你可以编写一个查询来拉回所用的参数,哦看看有人使用了初始加载过滤器而不是日常。 Whoopsidaisy。同时关注并发执行和更改值。
  4. 表驱动方法。您不必使用配置SQL Server表支持,而是滚动自己的表,然后在您的包中添加一个执行SQL任务,以将过滤器Single Row检索到QueryFilter变量中。
  5. 脚本任务。使用漂浮在船上的任何东西来确定过滤器应该是什么。
  6. 消息队列。它们内置了Message Queue Task,如果您已经在使用它,可能会在这里使用它们。否则,管理太多的努力