使用 SSIS 中的参数作为 OLE DB 源执行存储过程

Posted

技术标签:

【中文标题】使用 SSIS 中的参数作为 OLE DB 源执行存储过程【英文标题】:Execute Stored Procedure with parameters in SSIS as OLE DB Source 【发布时间】:2019-08-20 09:41:26 【问题描述】:

我想执行一个需要参数作为 OLE DB 源的存储过程,以便稍后从 SSIS 将其导出为 Excel 文件。

SP 生成一组我想导出到 Excel 文件的数据

这是我为 SP 运行的代码。 (这样运行会产生我想要的结果)

DECLARE @RC int
DECLARE @startweek varchar(20)
DECLARE @endweek varchar(20)
DECLARE @payroll varchar(30)
DECLARE @job varchar(25)
DECLARE @job_to varchar(25)
DECLARE @manager varchar(30)
DECLARE @office varchar(100)
DECLARE @pu varchar(6)
DECLARE @pu_to varchar(6)
DECLARE @task varchar(25)
DECLARE @task_to varchar(25)
DECLARE @Prj_pu varchar(6)
DECLARE @Prj_pu_to varchar(6)

SET @endweek = dateadd(d, -((datepart(weekday, getdate()) + 1 + @@DATEFIRST) % 7), getdate());
SET @startweek = DATEADD(WEEK, -25, @endweek)

EXECUTE @RC = [dbo].[TIME_lynx_extract] 
   @startweek
  ,@endweek 
  ,@payroll
  ,@job
  ,@job_to
  ,@manager
  ,@office
  ,@pu
  ,@pu_to
  ,@task
  ,@task_to
  ,@Prj_pu
  ,@Prj_pu_to
GO

我不确定运行的格式是否正确。

这是设置的图片:

这些是黄色背景部分的错误:

HRESULT 异常:0xC020204A

数据流任务 [OLE DB 源 [37]] 出错:SSIS 错误代码 DTS_E_OLEDBERROR。发生 OLE DB 错误。错误代码:0x80004005。

一个 OLE DB 记录可用。来源:“Microsoft SQL Server Native Client 11.0” Hresult:0x80004005 描述:“无法确定元数据,因为过程 'TIME_lynx_extract' 中的语句 'EXECUTE SP_EXECUTESQL @STR_SQL' 包含动态 SQL。考虑使用 WITH RESULT SETS 子句显式描述结果集。”。

数据流任务 [OLE DB 源 [37]] 出错:无法从数据源检索列信息。确保数据库中的目标表可用。

另外,如果我尝试在 OLE DB 源上执行基本查询,它可以工作,所以与数据库的连接似乎没问题。 现在的主要问题是如何执行这个 SP。

【问题讨论】:

IN 关于问题,打印屏幕底部有错误,您的问题中没有包含这些错误。我们真的需要这些。 那个也告诉你问题...我会强调部分:""无法确定元数据,因为过程'TIME_lynx_extract'中的语句'EXECUTE SP_EXECUTESQL @STR_SQL'包含动态 SQL。 考虑使用 WITH RESULT SETS 子句明确描述结果集。"。" Using EXECUTE to redefine a single result set 检查下面的答案可能会有所帮助***.com/questions/48083262/… 我建议这会对你有所帮助:***.com/questions/7610491/… 【参考方案1】:

在 DFT 中将参数与 EXEC 一起使用并不难。

首先,您需要确保所有输入参数值都有 SSIS 变量。

具体来说,制作所有这些 [User::var_name] 并填充它们(填充值超出了此答案的范围):

DECLARE @startweek varchar(20)
DECLARE @endweek varchar(20)
DECLARE @payroll varchar(30)
DECLARE @job varchar(25)
DECLARE @job_to varchar(25)
DECLARE @manager varchar(30)
DECLARE @office varchar(100)
DECLARE @pu varchar(6)
DECLARE @pu_to varchar(6)
DECLARE @task varchar(25)
DECLARE @task_to varchar(25)
DECLARE @Prj_pu varchar(6)
DECLARE @Prj_pu_to varchar(6)

另外,在您的 DFT 之前将您的 @endweek@startweek 设置为 Execute SQL Task

现在您已准备好所有 SSIS 变量,请返回到您的 OLE DB Source 任务,然后编辑您的查询。您需要删除返回变量,并更改所有输入参数,如下所示:

EXECUTE [dbo].[TIME_lynx_extract] ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?
WITH RESULT SETS(
(
worker_reference NVARCHAR(50),
placement_reference NVARCHAR(10),
worker_name NVARCHAR(50),
job_title NVARCHAR(100),
authorising_line_manager NVARCHAR(100),
timesheet_date DATETIME,
company_agent_name NVARCHAR(100),
type_of_worker NVARCHAR(100),
week_number NVARCHAR(10),
hours_worked NVARCHAR(10),
rate_description NVARCHAR(100),
rate_per_hour NVARCHAR(10),
job NVARCHAR(50),
work_stage NVARCHAR(100),
project_name NVARCHAR(100),
location NVARCHAR(100)
))

完成后,点击查询窗口旁边的Parameters 按钮。 SSIS 应该使用Parameter0Parameter12 预先填充列表。您要做的是检查所有这些 ParameterX 名称并将其更改为您的输入参数名称。然后为每个参数选择相应的 SSIS 变量。

当我为我的测试过程执行此操作时,我的Set Query Parameters 窗口如下所示:

【讨论】:

有了这个我能够让它工作,我现在正在生成我需要的 xlsx 文件:) 只需要弄清楚如何设置密码并通过电子邮件发送,但谢谢!这让我更接近了! @Baldie47 你介意解释一下你在 WITH RESULT SETS() 中使用的所有变量。是返回表的列标题吗? 不,这些是您需要传递给存储过程的参数(需要很多参数,这就是为什么它看起来很拥挤)所有这些参数都来自前面步骤的 SSIS。【参考方案2】:

好的,我将为 ssis 中的执行 SQL 任务任务回答这个问题。这些示例在 VS 2017 Enterprise 中有效。您可能会认为,当您添加 Execute SQL Task 时,ResultSet 和 Parameters 的语法将是相同的,无论您如何连接到数据库,但事实并非如此。 如果您使用与 ms sql 的 OLEDB 数据库连接,则使用一种语法,如果您使用 ADO.Net,则对 Parameter 和 ResultSet 使用另一种语法

如果您使用 OLEDB 连接到 MS Sql 和单行 ResultSet:

您的参数是输入,并且您指定 0 作为参数名称。你可以有一个参数长度。那么你的 MS Sql 是: set @myvar = (从 xwherecol = 的 mytable 中选择 mycol?) 问号?是您的参数替换的地方。如果您有多个输入参数,只需在参数映射的每一行中加载一个,ParameterName 为 0,1,2,...,然后使用多个问号。

OLEDB ResultSet 将采用命名结果,因此请设置您的 ResultName 到 xxxx,然后在你最后的 ms sql 中从 Execute SQL Task 中选择:

选择 @myvar 作为 xxxx 并且@myvar 将被放置在 xxxx ResultSet 变量中

如果您使用 ADO.Net 连接 ms sql 和单行 ResultSet:

您的参数是输入,在这里您指定参数的名称(我将使用 xyz (NO @) 作为参数映射窗格中的参数名称)。您的 MS Sql 是:

set @myvar = (select mycol from mytable as xwherecol = @xyz) 并且你没有在你的执行 SQL 任务的 ms sql 中声明 @xyz

对于 ResultSet,ADO.Net 不会采用命名的 ResultSet,因此在 ResultSet 中,对于您要返回的每个结果,您的 ResultName 只是 0,1,2 ...。 然后,您的最终选择只会按照您列出的顺序将您选择的列分配给 ResultSet。

不直观,但我希望这会有所帮助。此示例假设您正在连接到 ms sql,如果您正在连接到 Oracle 或 Teradata,我不确定我上面描述的内容是否有效。参数和结果集可能会起作用,但 sql 语法显然会有所不同。

【讨论】:

以上是关于使用 SSIS 中的参数作为 OLE DB 源执行存储过程的主要内容,如果未能解决你的问题,请参考以下文章

SSIS - 检查 OLE DB 源架构

SSIS - 将 Fact 与查找表匹配两次时重用 Ole DB 源

将参数传递给 OLE DB SOURCE

SSIS - 如何从平面文件插入到具有日期范围的OLE DB?

SSIS - OLE DB 目标 - 表或视图加载与快速加载

SSIS 2005 - 在数据流中的 OLE DB 源中具有 UPDATE *和* SELECT