此分步示例适用于可能偶然发现此问题的其他人。此示例使用 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