13

我们最近注意到一个问题,重新部署的 SSIS 包有时似乎不包含最新的更改...当我使用记事本搜索 dtsx 时,我在代码中看到了修改后的脚本,因此更改肯定存在。

我的假设是 SSIS 包的脚本组件最终会在过程中的某个位置编译成程序集——这很可能是因为我认为 C# 代码如果没有先编译它就无法运行。因此,理论上,如果这些程序集最终会被缓存并且不会立即被覆盖(出于某种原因),这将解释这个问题。

唯一让我认为我的理论是正确的“证据”是,如果我在某个时候继续运行包,它会突然转移到新代码。

但是,到目前为止,我还没有找到为什么以及如何发生这种情况,如果是......有人可以帮忙吗?

更新: MSDN 说:“与可以指示脚本是否已预编译的早期版本不同,所有脚本都在 SQL Server 2008 集成服务 (SSIS) 和更高版本中进行了预编译。” - 如果通过预编译它们意味着运行预编译版本而不是实际包(我认为这是因为包本身似乎没有被编译,因为代码在记事本中可见)必须有一种方法来强制引擎覆盖预编译的程序集......但是如何?

更新: SSIS 的四个核心组件之一是SQL ServerIntegration Services 服务,它是一个 Windows 服务。显然,该服务将缓存组件/任务元数据,以便 SSIS 运行时引擎可以轮询缓存以查看已安装的内容,这可能有助于加快包加载时间。但是,如果包存储在文件系统中(而不是 SQL 集成服务中)并由代理作业执行,则代理作业将使用 64 位版本的 DTEXEC 来执行包。我还没有找到任何证据表明那里会涉及任何缓存,但肯定有一些选项可以在执行的验证阶段检查许多参数,例如版本号 - 可能是有原因的。

4

3 回答 3

4

这对我不久前遇到的事情听起来有些熟悉。不幸的是,我不记得我到底是什么时候遇到这个的(所以我不能确定),但我相信我找到的修复是确保我之前明确地Build | Build st_5bd541c294054c25b9e7eb55b92bd0e2从脚本编辑器(VSTA)菜单调用了命令关闭窗口。(显然,每个脚本的具体项目名称会有所不同,因为它基于 GUID;但是,在 . 下只有一个可能的子菜单Build。)

显式调用该Build命令可确保脚本的二进制代码进行 ASCII 编码并保存在生成​​的 .dtsx 文件的 XML 中。我已经习惯了每次关闭脚本编辑器时总是为我构建的 SSIS 2005。显然,存在一些奇怪的边缘情况,即当编辑器关闭时,SSIS 2008 并不总是构建脚本项目。

顺便说一句,预编译的二进制文件似乎存储在源 XML 的标记中,称为BinaryItem

  <DTS:Executable DTS:ExecutableType="Microsoft.SqlServer.Dts.Tasks.ScriptTask.ScriptTask, Microsoft.SqlServer.ScriptTask, Version=10.0.0.0, Culture=neutral, PublicKeyToken=89845dcd8080cc91" DTS:ThreadHint="0">
    <DTS:Property DTS:Name="ObjectName">SCR_StepOne</DTS:Property>
    <DTS:ObjectData>
      <ScriptProject Name="ST_5bd541c294054c25b9e7eb55b92bd0e2" VSTAMajorVersion="2" VSTAMinorVersion="1" Language="CSharp" EntryPoint="Main" ReadOnlyVariables="User::FileOneName,User::OutputFolder" ReadWriteVariables="">
        <BinaryItem Name="\bin\release\st_5bd541c294054c25b9e7eb55b92bd0e2.csproj.dll">
          TVqQAAMAAAAEAAAA//8AALgAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
          AAAAgAAAAA4fug4AtAnNIbgBTM0hVGhpcyBwcm9ncmFtIGNhbm5vdCBiZSBydW4gaW4gRE9TIG1v
          ZGUuDQ0KJAAAAAAAAABQRQAATAEDADuOb04AAAAAAAAAAOAAAiELAQgAABAAAAAIAAAAAAAAPi8A
          AAAgAAAAQAAAAABAAAAgAAAAAgAABAAAAAAAAAAEAAAAAAAAAACAAAAAAgAAAAAAAAMAQIUAABAA

可能值得检查您的源代码控制系统历史记录,以查看是否已针对某些棘手的错误进行了更新。

警告:我还没有找到关于此的官方 Microsoft 文档。

于 2013-07-02T21:14:02.467 回答
4

您是否查看过 sysssispackages 以将 msdb 中包的版本内部版本号与 Visual Studio / SSIS 中的内部版本号进行比较?

SELECT name, verbuild
FROM msdb.dbo.sysssispackages
WHERE name LIKE '%bla%'

(根据需要调整 WHERE 子句以找到您的包。永远不要“SELECT * FROM msdb.dbo.sysssispackages”,因为它在其中一列中包含包 XML。)

在 Visual Studio 中,打开包,然后右键单击包的背景并从上下文菜单中选择“属性” 。查看字段 VersionBuild。它应该与上面 SELECT 中的数字匹配!

我知道这不是您问题的实际解决方案,但它可能有助于找出问题的原因所在。如果数字较旧,则意味着您的包部署不起作用。

于 2013-07-02T13:07:17.740 回答
2

这并没有专门解决您所拥有的谜团,但是如果您正在运行基于文件系统的包并且想要验证正在运行的包是您部署的包,那么有一种方法可以做到这一点。

  1. 构建你的包。
  2. 打开包上的属性并记下“版本构建”属性(或者,在记事本中打开 .dtsx 并找到 DTS:VersionBuild 属性。)
  3. 部署你的包。
  4. 在您的 SQL 代理作业步骤中,转到验证选项卡。
  5. 在“Verify package build”输入框中输入Version Build。
  6. 执行作业步骤。

我不知道这是否会强制 SSIS 丢弃其缓存并获取新部署的包,但我知道如果您手动修改 .dtsx 包的内部版本号,然后尝试重新运行作业步骤,它会失败,因为包构建与它正在寻找的不匹配,因此它肯定会对该值进行运行时检查。

于 2013-07-02T15:05:27.747 回答