【发布时间】:2015-02-27 06:44:43
【问题描述】:
我很擅长 SSIS,我创建了一个包,它将 excel 文件加载到 SQL SERVER 表中。
我编写了 C# 代码以仅提取第一个工作表名称,然后包将加载此第一个工作表(仅)存在的数据。
当我通过 BIDS 运行该软件包时,它运行良好。但是当我通过 SQL AGENT JOB 运行这个包时,同一个包在 C# 代码步骤中会引发错误。
我看到很多帖子暗示这可能是因为在 c# 代码中使用了Microsoft.interop.excel 引用。
在 C# 中是否有任何替代方法可以在不使用互操作库的情况下提取 excel 文件的第一个工作表名称(不基于升序)。
或者,当在代码中使用互操作时,如何配置 SQL AGENT 作业以成功运行?
我的服务器是 64 位的。
我尝试在“C:\Windows\System32\config\systemprofile\”中创建“桌面”文件夹
错误:描述:System.Reflection.TargetInvocationException: 调用的目标已引发异常。 ---> System.NullReferenceException:对象引用未设置为实例 的一个对象。在 ST_ecfa668f250a45e18c95639c9ffd64d4.csproj.ScriptMain.Main() --- 内部异常堆栈跟踪结束 --- 在 System.RuntimeMethodHandle._InvokeMethodFast(对象目标,对象 [] 参数,SignatureStruct& sig,MethodAttributes 方法属性, RuntimeTypeHandle typeOwner) 在 System.RuntimeMethodHandle.InvokeMethodFast(对象目标,对象 [] 参数,签名 sig,MethodAttributes methodAttributes, RuntimeTypeHandle typeOwner) 在 System.Reflection.RuntimeMethodInfo.Invoke(对象 obj,BindingFlags invokeAttr、Binder binder、Object[] 参数、CultureInfo 文化、 Boolean skipVisibilityChecks)在 System.Reflection.RuntimeMethodInfo.Invoke(对象 obj,BindingFlags invokeAttr、Binder binder、Object[] 参数、CultureInfo 文化)
在 System.RuntimeType.InvokeMember(字符串名称,BindingFlags bindingFlags, Binder binder, Object target, Object[] providedArgs, ParameterModifier[] 修饰符、CultureInfo 文化、String[] 命名参数)在 System.Type.InvokeMember(字符串名称,BindingFlags invokeAttr、Binder binder、Object 目标、Object[] args、CultureInfo 文化)在 Microsoft.SqlServer.Dts.Tasks.ScriptTask.VSTATaskScriptingEngine.ExecuteScript() 结束错误错误:2015-02-27 11:24:00.23 代码:0x00000001
来源:用户邮件描述: System.Reflection.TargetInvocationException:已引发异常 通过调用的目标。 ---> System.Data.SqlClient.SqlException:网络相关或 建立连接时发生特定于实例的错误 SQL 服务器。服务器未找到或无法访问。核实 实例名称正确且 SQL Server 配置为 允许远程连接。 (提供者:命名管道提供者,错误:40 - 无法打开与 SQL Server 的连接)在 System.Data.SqlClient.SqlInternalConnection.OnError(SqlException 异常,布尔型 breakConnection) 在 System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj) 在 System.Data.SqlClient.TdsParser.Connect(ServerInfo serverInfo, SqlInternalConnectionTds connHandler, 布尔值 ignoreSniOpenTimeout, Int64 timerExpire, Boolean encrypt, Boolean trustServerCert,布尔集成安全,SqlConnection 拥有对象)在 System.Data.SqlClient.SqlInternalConnectionTds.AttemptOneLogin(ServerInfo serverInfo,字符串 newPassword,布尔型 ignoreSniOpenTimeout,Int64 timerExpire, SqlConnection owningObject) 在 System.Data.SqlClient.SqlInternalConnectionTds.LoginNoFailover(字符串 主机,字符串 newPassword,布尔重定向用户实例, SqlConnection owningObject、SqlConnectionString connectionOptions、 Int64 timerStart)在 System.Data.SqlClient.SqlInternalConnectionTds.OpenLoginEnlist(SqlConnection 拥有对象,SqlConnectionString 连接选项,字符串 newPassword,布尔重定向用户实例)在 System.Data.SqlClient.SqlInternalConnectionTds..ctor(DbConnectionPoolIdentity 身份、SqlConnectionString 连接选项、对象 providerInfo、 字符串 newPassword、SqlConnection owningObject、布尔值 重定向用户实例)在 System.Data.SqlClient.SqlConnectionFactory.CreateConnection(DbConnectionOptions 选项,对象 poolGroupProviderInfo,DbConnectionPool 池, DbConnection 拥有连接)在 System.Data.ProviderBase.DbConnectionFactory.CreatePooledConnection(DbConnection owningConnection、DbConnectionPool 池、DbConnectionOptions 选项) 在 System.Data.ProviderBase.DbConnectionPool.CreateObject(DbConnection 拥有...包执行失败...步骤失败
C# 代码-
using System;
using System.Data;
using System.Diagnostics;
using Microsoft.SqlServer.Dts.Runtime;
using System.Windows.Forms;
using System.Data.OleDb;
using Microsoft.Office.Interop;
using System.Runtime.InteropServices;
namespace ST_ecfa668f250a45e18c95639c9ffd64d4.csproj
{
[System.AddIn.AddIn("ScriptMain", Version = "1.0", Publisher = "", Description = "")]
public partial class ScriptMain : Microsoft.SqlServer.Dts.Tasks.ScriptTask.VSTARTScriptObjectModelBase
{
#region VSTA generated code
enum ScriptResults
{
Success = Microsoft.SqlServer.Dts.Runtime.DTSExecResult.Success,
Failure = Microsoft.SqlServer.Dts.Runtime.DTSExecResult.Failure
};
#endregion
public void Main()
{ /*Passing the file path via User::File_Name Variable*/
string FileName = Dts.Variables["User::File_Name"].Value.ToString();
Microsoft.Office.Interop.Excel.Application xlApp = null;
Microsoft.Office.Interop.Excel.Workbook excelBook = null;
try
{
xlApp = new Microsoft.Office.Interop.Excel.Application();
excelBook = xlApp.Workbooks.Open(FileName, Type.Missing,
Type.Missing, Type.Missing, Type.Missing,
Type.Missing, Type.Missing, Type.Missing, Type.Missing,
Type.Missing, Type.Missing, Type.Missing, Type.Missing,
Type.Missing, Type.Missing);
string[] excelSheets = new string[excelBook.Worksheets.Count];
int i = 0;
foreach (Microsoft.Office.Interop.Excel.Worksheet wSheet in excelBook.Worksheets)
{
excelSheets[i] = wSheet.Name;
i++;
}
Dts.Variables["User::WorkSheetName"].Value = excelSheets[0] + "$";
}
catch (Exception ex)
{
excelBook.Close(false, FileName, null);
Marshal.ReleaseComObject(excelBook);
string error = ex.Message;
}
finally
{
excelBook.Close(false, FileName, null);
Marshal.ReleaseComObject(excelBook);
}
Dts.TaskResult = (int)ScriptResults.Success;
}
}
}
【问题讨论】:
-
Excel interop 是否在服务器上的 GAC 中注册?运行 SQL 代理的服务是否对所有相关文件夹和文件具有相同的读/写权限?
-
是的,Sql Agent 对文件夹具有管理员权限
-
我不明白,为什么 StackOverflow 将这个问题标记为否定,对他们来说这听起来很愚蠢吗?
-
尝试创建这个文件夹:C:\Windows\SysWOW64\config\systemprofile\Desktop
-
谢谢@Sorrell...我做了这个并且包运行成功...但是你能解释一下这背后的逻辑
标签: c# .net sql-server excel ssis