sql-server - SSIS 包在运行时挂起

标签 sql-server ssis

正如标题所暗示的那样,我在数据导入期间遇到了 SSIS 包的问题。 我将尽力描述需求、采取的方法、问题以及迄今为止我所尝试的内容。

需求:
将数据从 Excel 2007 文件(1.000.000 行)导入到 SQL 表。
文件是在 UI 的帮助下上传的,因此包必须接收文件路径作为参数
导入不得阻塞 UI
在 SQL 级别应用额外的业务验证
知道包裹是否失败的可能性
失败时回滚的可能性

方法:
我已经创建了一个 SSIS 包并在 BIDS 中成功测试了它
创建一个存储过程并在 xp_cmdshell 的帮助下调用 dtexec
创建了一个作业来不阻止 UI(并且还能够识别导入/业务需求是否仍在运行
填充一个表来存储包的参数(在我所做的研究中,我发现我无法将参数直接传递到作业或作业步骤)

构建对 dtexec 的调用的代码如下所示

DECLARE @SSIS NVARCHAR(4000) = '';
DECLARE @Params NVARCHAR(4000) = '/set \package.variables[FileName].Value;"\"' + @FileName + '\"" /set \package.variables[ConnectionString].Value;"\"' + @ConnectionString + '\""';
DECLARE @ExePath NVARCHAR(4000) = 'C:\"Program Files (x86)"\"Microsoft SQL Server"\100\DTS\Binn\'

SET @SSIS = @ExePath + 'dtexec /f "' + @PackageName + '" '
SET @SSIS = @SSIS + @Params

DECLARE @ReturnCode int
EXEC @ReturnCode = master..xp_cmdshell @SSIS

以及生成的行并由 xp_cmdshell 运行

C:\"Program Files (x86)"\"Microsoft SQL Server"\100\DTS\Binn\dtexec /f "C:\inetpub\wwwroot\pwc\\Import.dtsx" /set \package.variables[FileName].Value;"\"\\<server_name>\upload\Import.xlsx\"" /set \package.variables[ConnectionString].Value;"\"<connection_string>\""


问题:
在长时间运行(1 小时以上)后,程序包似乎挂起并且不执行任何操作,同时保持内存占用(在任务管理器中观察进程),尽管它应该需要大约 25 分钟。
所以,我的问题是:
1.什么会导致包挂起并无法完成
2. 当文件为 220mb 时,为什么 dtexec 占用约 2GB 内存(这是出于好奇;我可以忍受内存问题)

我尝试过的:
在 cmd 中运行该行。包运行成功,这让我认为这是 xp_cmdshell 的问题
我读到 xp_cmdshell 的权限可能存在问题,因此我当前正在以 SQL 管理员身份运行该作业
我找到了一些可以解释正在发生的事情的内容,但它与从应用程序运行包有关;如果这是问题所在,我将不胜感激有关 SQL 语法的帮助

非常感谢您帮助解决这个问题



更新
虽然手头的问题仍未解决,但我已经设法找到一种不同的方法来解决需求。
在我之前的声明中,我说过我不知道如何将参数传递给作业步骤。同时我找到了一种方法。它并不是真正直接的,但它确实解决了我的问题。 使用job step updatepermissions needed for update ,我成功修改了作业步骤的注释字段

EXEC msdb.dbo.sp_update_jobstep
@job_name = N'StartImportFlow',
@step_id = 1,
@command  = <my command> ;

由于能够修改作业步骤,我将对包的调用从存储过程移至作业步骤。
需要提醒一件事:要执行从服务器代理打包的 DTS,该步骤必须在 sysadmin 帐户下运行,否则需要代理来允许执行。



我希望得到一些关于如何处理当前问题的提示:我应该将其标记为已回答,还是应该让它像这样来回答最初的问题?

最佳答案

根本原因

有一个known issue使用 xp_cmdshell 只允许处理一组双引号参数。

分辨率

  1. 您可以走工作步骤路线。这种方法的缺点是您只能运行一个实例。我不知道 UI 是如何实现的,但并发上传可能很难看。

  2. 创建运行包的批处理文件。它将获取文件名和连接参数,这可能会让您只传入一组双引号参数。

  3. 我对不阻止 UI 的要求感到有点困惑,但它需要了解包失败。一种选择是让 UI 将所有启动参数写入表中。然后安排一个进程每隔 N 个时间间隔运行一次,并使用所述参数启动这些包,并将结果写回到该表或另一个表中。您还可以直接从 UI 启动该包。虽然您可以使用 dtexec,但此时由于您正在编写自定义代码,因此只需使用对象模型即可完成。

伪代码大约

using Microsoft.SqlServer.Dts;

string fileName = @"\\network\path\file.dtsx";
Application app = new Application();
Package p = app.LoadPackage(fileName, null);
p.Variables["FileName"].Value = @"\\network\path\file.xlsx";
p.Variables["ConnectionString"].Value = @"whatever works";
DTSExecResult results = currentPackage.Execute();

关于sql-server - SSIS 包在运行时挂起,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15921093/

相关文章:

sql-server - SQL Server查询从每个子组中选择1

sql-server - SSIS 组件不会失败或重定向

sql - 等于操作中 “Latin1_General_CI_AS”和 “SQL_Latin1_General_CP1_CI_AS”之间的冲突

visual-studio-2008 - 我的 Visual Studio 2008 中缺少 SSIS "Save Copy of ..."

sql-server - 在哪里可以获得 Visual Studio Tools for Applications 2008

ssis - 如何在 ssis 包中的平面文件目标中保留空值

sql-server - 这是在存储过程中使用可选参数的正确方法吗?

sql-server - SQL Server Integration Services SSIS 2005 - 如何让用户运行包?

sql-server - 为什么 ADO NET Source 默认显示不正确的字符串数据类型?

sql-server - 如何强制重新编译 Linq to SQL 查询的执行计划?