【问题标题】:How do I access Excel data source from an SSIS package deployed on a 64-bit server?如何从部署在 64 位服务器上的 SSIS 包访问 Excel 数据源?
【发布时间】:2008-08-21 23:42:39
【问题描述】:

我有一个 SSIS 包,可以将数据导出到几个 Excel 文件以传输给第三方。为了让它在 64 位服务器上作为计划作业运行,我知道我需要将步骤设置为 CmdExec 类型并调用 32 位版本的 DTExec。但我似乎无法获得正确的命令来传递 Excel 文件的连接字符串。

到目前为止,我有这个:

DTExec.exe /SQL \PackageName /SERVER OUR2005SQLSERVER /CONNECTION 
LETTER_Excel_File;\""Provider=Microsoft.Jet.OLEDB.4.0";"Data 
Source=""C:\Temp\BaseFiles\LETTER.xls";"Extended Properties=
""Excel 8.0;HDR=Yes"" /MAXCONCURRENT " -1 " /CHECKPOINTING OFF /REPORTING E

这给了我错误:Option "Properties=Excel 8.0;HDR=Yes" is not valid.

我尝试了几个引号的变体,但还没有弄好。

有谁知道如何解决这个问题?

UPDATE:

感谢您的帮助,但我现在决定使用 CSV 文件,因为它们似乎只适用于 64 位版本。

【问题讨论】:

  • stackoverflow.com/questions/753211/…。如果调用 32 位版本的 DTExec,一切正常。您可以在 Program Files (x86) 目录下的相同结构中找到它,也可以在 C:\Program Files\Microsoft SQL Server\90\DTS.x86\Binn 中找到它
  • 顺便说一句,CSV 文件只有在使用 XML 标记作为字段分隔符时才有效。如果他们在字段数据中有硬返回 ,那么您确实无能为力。
  • 另外,请确保将批处理限制为大约 1000 条记录。我总是让 DTS 包在 10,000 条记录时失败,这是默认设置。

标签: sql-server excel ssis


【解决方案1】:

此分步示例适用于可能偶然发现此问题的其他人。此示例使用 SSIS 2005 并使用 SQL Server 2005 64 位版本服务器 运行作业。

这里的答案仅集中在修复问题中提到的错误消息上。该示例将演示重新创建问题的步骤以及问题的原因以及解决方法。

NOTE: 我建议使用将包配置值存储在数据库中的选项或在环境变量的帮助下使用间接 XML 配置。此外,创建 Excel 文件的步骤将使用模板完成,然后通过移动到不同的文件夹进行存档。本文不讨论这些步骤。如前所述,这篇文章的目的是解决错误。

让我们继续这个例子。我还写了关于这个答案的博客,可以在this link 中找到。答案是一样的。

创建一个 SSIS 包 (Steps to create an SSIS package)。此示例使用 BIDS 2005。我以 YYYYMMDD_hhmm 开头的格式命名包,然后是 SO 代表 Stack Overflow,然后是 SO 问题 ID,最后是描述。我并不是说你应该这样命名你的包。这是为了让我以后可以轻松地引用它。请注意,我还有一个名为 Adventure Works 的数据源。我将使用 Adventure Works 数据源,它指向从 this link 下载的 AdventureWorks 数据库。该示例使用 SQL Server 2008 R2 数据库。请参阅屏幕截图#1

在 AdventureWorks 数据库中,使用以下给定脚本创建一个名为 dbo.GetCurrency 的存储过程。

CREATE PROCEDURE [dbo].[GetCurrency]
AS
BEGIN
    SET NOCOUNT ON;
    SELECT 
    TOP 10      CurrencyCode
            ,   Name
            ,   ModifiedDate 
    FROM        Sales.Currency
    ORDER BY    CurrencyCode
END
GO

在包的连接管理器部分,右键单击并选择从数据源新建连接。在选择数据源对话框中,选择Adventure Works,然后单击“确定”。您现在应该会在 Connection Managers 部分下看到 Adventure Works 数据源。

在包的 Connection Managers 部分,再次右键单击,但这次选择 New Connection...。这是为了创建 Excel 连接。在添加 SSIS 连接管理器上,选择 EXCEL。在 Excel 连接管理器上,输入路径 C:\Temp\Template.xls。当我们将其部署到服务器时,我们将更改此路径。我选择了 Excel 版本 Microsoft Excel 97-2005 并选择保留复选框 First row has column names 选中,以便创建 Excel 文件时创建列标题。单击确定。将 Excel 连接重命名为 Excel,以保持简单。参考截图#2 - #7

在包上,创建以下变量。参考截图#8

  • SQLGetData:这个变量是字符串类型的。这将包含存储过程执行语句。此示例使用值 EXEC dbo.GetCurrency

屏幕截图#9显示了存储过程执行语句的输出EXEC dbo.GetCurrency

在包的“控制流”选项卡上,放置 Data Flow task 并将其命名为“导出到 Excel”。参考截图#10

双击数据流任务切换到数据流选项卡。

在“数据流”选项卡上,放置一个OLE DB Source 以连接到 SQL Server 数据以从存储过程中获取数据并将其命名为 SQL。双击 OLE DB Source 以打开 OLE DB Source Editor。在连接管理器部分,从 OLE DB 连接管理器中选择 Adventure Works,从数据访问模式中的变量中选择 SQL 命令,然后从变量中选择变量 User::SQLGetData名称下拉。在列部分,确保列名映射正确。单击“确定”关闭 OLE DB 源代码编辑器。请参阅屏幕截图 #11#12

在“数据流”选项卡上,放置 Excel Destination 以将数据插入 Excel 文件并将其命名为 Excel。双击 Excel 目标以打开 Excel 目标编辑器。在连接管理器部分,从 OLE DB 连接管理器中选择 Excel,然后从数据访问模式中选择表或视图。此时,我们没有 Excel,因为在创建 Excel 连接管理器时,我们只是指定了路径,但从未创建文件。因此,Excel 工作表的下拉名称中不会有任何值。因此,单击 New... 按钮(第二个 New)以创建一个新的 Excel 工作表。在“创建表”窗口中,BIDS 会根据传入的数据源自动提供创建表。您可以根据自己的喜好更改这些值。我将通过保留默认值来简单地单击“确定”。工作表的名称将填充在 Excel 工作表的下拉名称中。工作表的名称取自任务名称,在本例中为 Excel 目标,我们将其命名为 Excel。在 Mappings 部分,确保正确映射列名。单击“确定”关闭 Excel 目标编辑器。参考截图#13 - #16

配置数据流任务后,它应该如屏幕截图#17所示。

按 F5 执行包。屏幕截图 #18 - #21 显示了控制流和数据流任务中包的成功执行。此外,该文件是在 Excel 连接中提供的路径 C:\Temp\Template.xls 中生成的,并且存储过程执行输出中显示的数据与写入文件的数据相匹配。p>

在我的本地机器上开发的包在文件夹路径C:\Learn\Learn.VS2005\Learn.SSIS。现在,我们需要将文件部署到承载 64 位版本 SQL Server 的服务器上以安排作业。因此,服务器上的文件夹将是 D:\SSIS\Practice。从本地计算机复制包文件 (.dtsx) 并将其粘贴到服务器文件夹中。此外,为了使包正确运行,我们需要在服务器上提供 Excel 电子表格。否则,验证将失败。通常,我会创建一个模板文件夹,其中包含与输出匹配的空 Excel 电子表格文件。稍后,在运行时,我将使用包配置将 Excel 输出路径更改为不同的位置。对于这个例子,我将保持简单。所以,让我们将本地机器生成的 Excel 文件复制到路径 C:\Temp\Template.xls 到服务器位置 D:\SSIS\Practice。我希望 SQL 作业生成名称为 Currencies.xls 的文件。因此,将文件 Template.xls 重命名为 Currencies.xls。参考截图#22

为了表明我确实要在 64 位版本的 SQL Server 上运行该作业,我在 SQL Server 上执行了命令 SELECT @@version 并截图#23显示结果。

我们将使用 Execute Package Utility (dtexec.exe) 来生成命令行参数。登录到将在 SQL 作业中运行 SSIS 包的服务器。双击包文件,这将带来执行包实用程序。在 General 部分,从 Package source 中选择 File system。单击省略号并浏览到包路径。在 Connection Managers 部分,选择 Excel 并将 Excel 文件中的路径从 C:\Temp\Template.xls 更改为 D:\SSIS\Practice\Currencies.xls。在实用程序中所做的更改将在命令行部分生成相应的命令行。在命令行部分,复制包含所有必要参数的命令行。我们不会从这里执行包。点击关闭。参考截图#24 - #26

接下来,我们需要设置一个作业来运行 SSIS 包。我们不能选择 SQL Server Integration Services 包类型,因为它将在 64 位下运行并且找不到 Excel 连接提供程序。因此,我们必须将其作为Operating System (CmdExec) 作业类型运行。转到 SQL Server Management Studio 并连接到数据库引擎。展开 SQL Server 代理并右键单击作业节点。选择新工作...。在作业属性窗口的常规部分,提供作业名称为 01_SSIS_Export_To_Excel,所有者将是创建作业的用户。我有一个名为 SSIS 的类别,所以我会选择它,但默认类别是 [Uncategorized (Local)] 并提供简要说明。在“步骤”部分,单击 New... 按钮。这将带来 Job Step 属性。在作业步骤属性的常规部分,提供步骤名称为导出到 Excel,选择类型Operating system (CmdExec),将默认运行身份帐户保留为 SQL Server 代理服务帐户并提供以下命令。单击确定。在“新建作业”窗口中,单击“确定”。参考截图#27 - #31

C:\Program Files (x86)\Microsoft SQL Server\90\DTS\Binn\DTExec.exe /FILE 
"D:\SSIS\Practice\20110723_1015_SO_21448_Excel_64_bit_Error.dtsx" 
/CONNECTION Excel;"\"Provider=Microsoft.Jet.OLEDB.4.0;Data 
Source=D:\SSIS\Practice\Currencies.xls;Extended Properties=""EXCEL 8.0;HDR=YES"";\""  
/MAXCONCURRENT " -1 " /CHECKPOINTING OFF  /REPORTING EWCDI

新作业应出现在 SQL Server 代理 -> 作业节点下。右键单击新创建的作业 01_SSIS_Export_To_Excel 并选择 Start Job at Step…,这将开始作业执行。该作业将按预期失败,因为这是此问题的上下文。单击关闭以关闭“启动作业”对话框。请参阅屏幕截图 #32#33

让我们来看看发生了什么。转到 SQL Server 代理和作业节点。右键单击作业 01_SSIS_Export_To_Excel 并选择查看历史记录。这将带来日志文件查看器窗口。您可以注意到作业失败。展开红叉附近的节点并单击 Step ID 值为 1 的行。在底部,您可以看到错误消息 Option “8.0;HDR=YES’;” is not valid. 单击 Close 关闭 Log File Viewer 窗口。请参阅屏幕截图 #34#35

现在,右键单击作业并选择属性以打开作业属性。您也可以双击作业以显示作业属性窗口。单击左侧部分的步骤。并单击编辑。将命令替换为以下命令,然后单击确定。单击“作业属性”上的“确定”关闭窗口。右键单击作业 01_SSIS_Export_To_Excel 并选择 Start Job at Step…,这将开始作业执行。该作业将失败执行成功。单击关闭以关闭“启动作业”对话框。让我们来看看历史。右键单击作业 01_SSIS_Export_To_Excel 并选择查看历史记录。这将带来日志文件查看器窗口。您可以注意到该作业在第二次运行期间成功。展开绿色勾十字附近的节点,然后单击 Step ID 值为 1 的行。在底部,您可以看到消息 Option The step succeeded。单击关闭以关闭日志文件查看器窗口。文件 D:\SSIS\Practice\Currencies.xls 将成功填充数据。如果您多次成功执行该作业,数据将附加到文件中,您将找到更多数据。正如我之前提到的,这不是生成文件的正确方法。创建此示例是为了演示此问题的修复。参考截图#36 - #38

屏幕截图#39 显示了工作和非工作命令行参数之间的区别。右边是工作命令行,左边是不正确的。它需要另一个带有反斜杠转义序列的双引号来修复错误。可能有其他方法可以很好地解决此问题,但此选项似乎有效。

因此,该示例演示了一种在从部署在 64 位服务器上的 SSIS 包访问 Excel 数据源时修复命令行参数问题的方法。

希望对某人有所帮助。

截图:

#1:Solution_Explorer

#2:New_Connection_Data_Source

#3: Select_Data_Source

#4:New_Connection

#5:添加_SSIS_Connection_Manager

#6: Excel_Connection_Manager

#7: Connection_Managers

#8:变量

#9: Stored_Procedure_Output

#10: Control_Flow

#11: OLE_DB_Source_Connections_Manager

#12: OLE_DB_Source_Columns

#13: Excel_Destination_Editor_New

#14: Excel_Destination_Create_Table

#15: Excel_Destination_Edito

#16: Excel_Destination_Mappings

#17:数据流

#18:Successful_Package_Execution_Control

#19:Successful_Package_Execution_Data_Flow

#20: C_Temp_File_Created

#21:Data_Populated

#22: File_On_Server

#23: SQL_Server_Version

#24: Execute_Package_Utility_General

#25: Execute_Package_Utility_Connection_Managers

#26: Execute_Package_Utility_Command_Line

#27: Job_New_Job

#28:New_Job_General

#29:New_Job_Step

#30: New_Job_Step_General

#31:New_Job_Steps_Added

#32: Job_Start_Job_at_Step

#33: SQL_Job_Execution_Failure

#34: View_History

#35: SQL_Job_Error_Message

#36: SQL_Job_Execution_Success

#37: SQL_Job_Success_Message

#38: Excel_File_Generated

#39:Command_Comparison

【讨论】:

  • -1 因为这是excruciatingly长,对于一个相对简单的问题。言归正传。 SO 是一个问答系统,而不是教程库。
  • @piers7:我对 SO 的理解是为社区发布一个有用的答案,而 not 只是为了 OP。
  • 一个有用的答案是简洁明了。在大量教程中埋葬OP问题的实际答案对任何人都没有帮助。你还不如建议他去读一本书,因为答案就在某个地方。
  • 如果你想写一篇扩展教程,我建议你写博客,在你的答案中引用相关部分,并链接到文章的其余部分,供任何想了解更多信息的人使用。
【解决方案2】:

您可以在 64 位环境中使用 Excel 连接。 转到包配置属性。

调试 -> 调试选项 -> Run64BtRuntime -> 更改为 False 此外,如果您使用 SQL 代理,请转到作业步骤属性,然后检查 32 位运行时。

注意:这仅适用于 Visual Studio 中的调试...

【讨论】:

    【解决方案3】:

    没有 64 位 Jet OLEDB 提供程序,因此您无法从 64 位 SSIS 访问 Excel 文件。

    但是,即使在 64 位服务器上,您也可以使用 32 位 SSIS。安装 64 位版本时已经安装,您只需运行 32 位 DTEXEC.EXE - 安装的 Program Files (x86)\Microsoft Sql Server\90\Dts\Binn(将 90 替换为 100 如果您使用的是 SSIS 2008)。

    【讨论】:

      【解决方案4】:

      除非是业务需求,否则我建议您将连接字符串从命令行移动到包中,并使用包配置来定义 Excel 文件的路径(以免对其进行硬编码)。这将使其更易于维护。

      1. 定义一个变量@ExcelPath
      2. 使用连接的 Expression 属性构造连接字符串 - 示例:"Data Source=" + @[User::FilePath] + ";Provider=Microsoft.Jet.OLEDB.4.0;Extended Properties=dBASE IV;"
      3. 在包配置中为 @ExcelPath 赋值。

      仔细看看上面的连接字符串。它取自一个工作包。我不确定这一点,但也许你根本不需要任何引号(上面的那些只是因为表达式编辑器需要它们)。


      I have also had some problems with SSIS on 64-bit SQL Server 2005.我博客中的那篇文章没有回答你的问题,但它有些相关,所以我发布了链接。

      【讨论】:

        【解决方案5】:

        我有点像 Zim 博士所做的那样,但我将 DTExec 文件 C:\Program Files (x86)\Microsoft SQL Server\90\DTS\Binn\DTExec.exe 复制到 C:\Program Files\Microsoft SQL Server\90\DTS\Binn\ 文件夹,但将 32 位文件命名为 DTExec32.exe

        然后我能够通过存储过程运行我的 SSIS 脚本:

        set @params = '/set \package.variables[ImportFilename].Value;"\"' + @FileName + '\"" '
        set @cmd =  'dtexec32 /SQ "' + @packagename + ' ' + @params + '"'
        --DECLARE @returncode int
        exec master..xp_cmdshell @cmd
        --exec @returncode = master..xp_cmdshell @cmd
        --select @returncode
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-07-08
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多