【问题标题】:Passing a variable through DTEXEC with xp_cmdshell (SQL Server 2008)使用 xp_cmdshell (SQL Server 2008) 通过 DTEXEC 传递变量
【发布时间】:2012-06-11 15:07:12
【问题描述】:

我创建了一个 SSIS 包,可将 Excel 文件导入我的数据库。我创建了一个变量,我想将其用作 Excel 连接管理器的 Excel 文件路径。

我的 SSIS 包中的变量名称是“ExcelSource”,它应该代表完整路径。我想最终动态设置它,因为文件名包含日期。

运行它的 T-SQL 代码是什么?这是我目前所拥有的:

DECLARE @ssisstr VARCHAR(8000)
, @packagename VARCHAR(200)
, @servername VARCHAR(100)

DECLARE @params VARCHAR(8000)
--my package name
SET @packagename = 'MyPackage'
--my server name
SET @servername = 'MYCOMPUTER\MYSERVER'

SET @params = '/set \package.variables[ExcelSource].Value;"\"Y:\excelFile\Test File - June 11 2012.xlsx\""'

SET @ssisstr = 'dtexec /sq ' + @packagename + ' /ser ' + @servername + ' '
SET @ssisstr = @ssisstr + @params

DECLARE @returncode INT
EXEC @returncode = xp_cmdshell @ssisstr
SELECT @returncode

【问题讨论】:

    标签: sql dynamic ssis


    【解决方案1】:

    您将遇到的问题是使用 xp_cmdshell 转义值。对于运行带有复杂命令行参数的包时遇到的另一个问题,我无法解决这个问题。如果有人可以提供相反的信息,请告诉我,我将修改/删除我的回复。

    我可以建议作为解决您问题的替代方法是让您的包确定当前文件是什么,或者使用不同的机制来指导该行为。

    包,认识你自己

    这种方法是我的首选方法。您为您的软件包提供智能以解决问题。 如何知道正确的 Excel 文件是什么?你说它有一个日期,那么你怎么知道那个日期是什么?

    如果是今天的日期,您可以在变量上使用表达式 some 以提供的格式粘贴到当前日期。

    它是文件夹中唯一的文件吗?然后使用文件类型的 ForEach 枚举器来识别那里的所有 .xlsx 文件。这个问题和most excellent answer ;) 描述了如何使用 SSIS 导入最新的 CSV。查找最新的 Excel 文件 string fileMask = "*.xlsx";

    如果您有描述如何确定正确文件的业务规则,我很乐意提供有关如何使用 SSIS 实施该规则的见解。

    告诉我你想要什么

    另一个选项是使用外部配置来提供运行时值。 SSIS 提供了许多开箱即用的配置选项。我宁愿为此目的使用 SQL Server,但您的选择是

    • SQL Server 表
    • XML 文件
    • 环境变量
    • 注册表值
    • 父包

    最后 3 个是我认为的特殊用例,对您的问题不是特别方便,但为了完整起见,我列出了它们。无论您使用何种配置选项,点击 SSIS、Package Configuration、选中启用配置按钮并使用向导设置您的配置类型应该是一件简单的事情。

    使用外部配置的第二个选项是做你正在做的事情,提供命令行选项来控制包的行为(不需要更改包)。相反,您用 xp_commandshell 换取一些自定义 PowerShell。我认为 PS 只是 2008+ 的一个选项,但您可以编写一个相当简单的脚本来导入 SSIS 对象模型、创建应用程序的实例、打开现有包、应用命令行参数并运行应用程序。我可能会根据 answer over here 中的 $app 和 $package 位来拼凑一些东西

    编辑

    1) 您看到“选项 12.0 无效”的原因是 xp_cmdshell 贪婪并急切地将命令行选项中的空格作为单独的参数进行解析。如果你开始搜索 xp_cmdshell 的限制,你会得到很多命中,因为参数中的空格会导致问题。

    2) 据我所知,SQL 代理作业是静态的。能够将它们配置为使用可变值参数(在运行时评估的东西)调用任何步骤(sql、ssis 等)真是太棒了,但一般来说,我还没有找到这样做的干净方法。

    3) 如果您打算不更改包以确定“正确”文件是什么,使用配置或滚动您自己的调用方法(PS 是 SQL 代理中的作业步骤类型),您可以尝试低- 使用现有逻辑构建 dtexec 调用的技术解决方案,但将其全部保存在 .bat 文件中。 xp_cmdshell 然后调用批处理文件,它不应该处理参数名称中的空格。

    【讨论】:

    • 日期将是今天的日期。我很想在 SQL Server 中尽可能多地做这件事。当我使用命令行和 32 位版本的 dtexec 运行它时,我不断收到可怕的“选项 12.0 无效”错误。我可以让 SQL Server 代理运行它吗?
    • 我已经在线添加了我的回复。
    • 我实际上已经想出了如何使用 SQL 代理作业来运行它。但是,我还不能在 SSIS 中动态更改文件名。我正在使用脚本任务来执行此操作,但在设置变量时遇到了一些麻烦。我快到了。
    • 右键单击平面文件连接管理器并选择属性。找到表达式并单击省略号 (...) 在左侧下拉菜单中选择 ConnectionString,右手将需要变量 @[User::ExcelSource]
    • 谢谢,我就是这么做的。我现在无法使用脚本任务设置变量。我将脚本任务连接到控制流窗口中的数据流任务。两者都成功执行,但我不确定 SSIS 是否按顺序正确执行它们。除了用箭头连接它们,我还需要做什么吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-04-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多