【问题标题】:SQL Server Agent and SSIS packagesSQL Server 代理和 SSIS 包
【发布时间】:2019-02-20 17:02:19
【问题描述】:

我正在尝试将变量值从 SQL Server 代理作业传递到 SSIS 包,但该变量中包含一个撇号,导致 SQL Server 代理作业失败

例如,在作业步骤属性的 SQL Server 代理中,我正在输入以下详细信息:

Property Path: \Package.Variables[User::VariableName].Properties[Value] Property 
Value: Michael O'Callaghan.

知道如何解决这个问题吗?

【问题讨论】:

    标签: sql-server ssis etl sql-job sql-agent


    【解决方案1】:

    如果包部署到 SSISDB 并从那里执行,请使用 SSISDB 存储过程设置值并转义引号,就像通过 T-SQL 一样。然后,SQL 代理作业可以为此步骤使用 T-SQL 脚本。下面的示例使用set_execution_parameter_value 存储过程来设置此值,并且仍然会导致“Michael O'Callaghan”被传入。

    DECLARE @execution_id BIGINT
    EXEC [SSISDB].[catalog].[create_execution] @package_name=N'Package.dtsx', @execution_id=@execution_id OUTPUT, 
    @folder_name=N'Project Folder', @project_name=N'Project', @use32bitruntime=False, @reference_id=Null
    
    DECLARE @var0 SQL_VARIANT = N'Michael O''Callaghan'
    EXEC [SSISDB].[catalog].[set_execution_parameter_value] @execution_id,  @object_type=30, @parameter_name=N'Name', @parameter_value=@var0
    
    DECLARE @var1 SMALLINT = 1
    EXEC [SSISDB].[catalog].[set_execution_parameter_value] @execution_id,  @object_type=50, @parameter_name=N'LOGGING_LEVEL', @parameter_value=@var1
    
    EXEC [SSISDB].[catalog].[start_execution] @execution_id
    

    【讨论】:

    • 为什么不使用存储的环境变量?
    • 好点@JWeezy,从环境变量中设置也可以。
    • @JWeezy 最好将此添加为另一个答案,因此 OP 有所有可能的解决方案,或者您可以编辑以下答案并添加此建议
    • @Hadi 根据您的建议,我提供了单独的答案。谢谢。
    【解决方案2】:

    逃脱它。只需使用双撇号。 '' (不是引用 ",而是撇号撇号)

    【讨论】:

      【解决方案3】:

      尝试维护配置文件的标准方法(如果您使用的是 2008 或更低版本)并通过文件传递变量值。

      【讨论】:

      • SSIS 项目部署模式具有自己的现代配置方式。它不再使用配置文件
      • @AlexanderVolok 我建议使用 2008 版本。编辑了我的答案。
      • 你说得对。 OP 尝试配置以“包模式”部署的包...我对使用项目部署模式的答案感到困惑
      【解决方案4】:

      另一种处理方法,坦率地说,我认为最好的方法是使用环境变量。据我所知,这是在 Microsoft 推出使用 SQL Server 2012 的项目部署模型作为包部署模型的替代品时引入的。包部署模型要求在要部署到服务器的单独 XML 文件中指定包参数。通过项目部署模型,Microsoft 在 SQL Server 中创建了一个用户友好的用户界面来管理这一点 - XML 文件已被删除。

      简而言之,环境变量允许开发人员将包参数(但不是包变量,因为它们是包本身的内部变量)链接到 SQL Server,从而在服务器上公开它们。这使得管理跨包存在的相同包参数(例如,连接管理器、FQDN 格式的网络文件夹位置等)变得非常容易管理。这里的想法是,如果包需要指向新的服务器或新的网络文件夹,那么开发人员可以简单地更改 SQL Server 中的单个值,然后传播到所有包而不需要打开、更改和重新部署包。

      有关如何执行此操作的详细步骤,请参阅以下参考资料:

      微软:这个有点干,但是很全面,出自马口。

      SQL Chick:更直观并提供屏幕截图,我觉得这很有帮助。

      【讨论】:

        【解决方案5】:

        感谢您的所有建议,但不幸的是它们没有奏效,但我为此构建了一个聪明的解决方法。

        SQL server 代理用单引号将变量值包装起来,例如在 sql server 代理中指定 Jon Doe,代理会像“Jon Doe”一样包装它并将其传递给 SSIS 包,所以如果你要输入一个带有撇号它会破坏 sql server 代理作业并且不会执行 SSIS 包它看起来像这个 E.G 传递这个值:'John O' Doe' 这会导致代理工作中断,所以你需要传递你的变量值as : John O''Doe 和代理将其包装如下:'John O''''Doe' 所以你需要在你的 SSIS 包中包含以下逻辑:

        声明@TempVar nVarchar(50) SET @TempVar = REPLACE(?, '''''', CHAR(39))

        上面的代码创建了一个变量来存储参数值。它将 4 个单引号替换为一个。 CHAR(39) 是单引号的 ASCII 表示。 这将导致变量值看起来像 John O'Doe。 希望这会有所帮助。

        我想从代理传递变量值的原因是我必须经常从 SSIS 包中更改变量值,每次都需要部署它。所以这种方式比较快。

        【讨论】:

          猜你喜欢
          • 2017-07-05
          • 1970-01-01
          • 2020-02-21
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-08-16
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多