使用SSIS包到Access DB的SQL Agent作业失败

sir*_*ide 14 sql-server oledb ssis sql-agent

我有一个运行脚本任务的SSIS包(主要是和其他一些东西).脚本任务使用OleDB连接连接到Access数据库.这是Microsoft Jet 4.0连接.我安装了驱动程序.但它不会通过代理帐户在SQL Agent中运行.它可以直接从Visual Studio和包存储中运行.事实上,当我以代理所附带的特殊帐户登录时,它在这两个地方都运行良好.但是,当我通过SQL Server代理运行时,我得到了可怕的"未指定错误"OleDbException.

脚本任务的相关代码:

// class field
private string accessConnectionStringTemplate = "Data Source=\"{0}\";Provider=Microsoft.Jet.OLEDB.4.0;";

// in method that connects to database
Print(file, "Connection string: " + string.Format(accessConnectionStringTemplate, file.FileName));
// outputs: Data Source = "\Path\To\File";Provider=Microsoft.Jet.OLEDB.4.0"
using(access = new OleDbConnection(string.Format(accessConnectionStringTemplate, file.FileName))) {
     access.Open();
     // other code
}
Run Code Online (Sandbox Code Playgroud)

通过SQL代理作业历史记录的错误消息:

Started:  12:35:10 PM
Error: 2016-11-03 12:35:33.51
   Code: 0x00000000
   Source: Import Files Main
   Description: Exception: Unspecified error
End Error
Error: 2016-11-03 12:35:33.51
   Code: 0x00000000
   Source: Import Files Main
   Description:    at System.Data.OleDb.OleDbConnectionInternal..ctor(OleDbConnectionString constr, OleDbConnection connection)
   at System.Data.OleDb.OleDbConnectionFactory.CreateConnection(DbConnectionOptions options, DbConnectionPoolKey poolKey, Object poolGroupProviderInfo, DbConnectionPool pool, DbConnection owningObject)
   at System.Data.ProviderBase.DbConnectionFactory.CreateConnection(DbConnectionOptions options, DbConnectionPoolKey poolKey, Object poolGroupProviderInfo, DbConnectionPool pool, DbConnection owningConnection, DbConnectionOptions userOptions)
   at System.Data.ProviderBase.DbConnectionFactory.CreateNonPooledConnection(DbConnection owningConnection, DbConnectionPoolGroup poolGroup, DbConnectionOptions userOptions)
   at System.Data.ProviderBase.DbConnectionFactory.TryGetConnection(DbConnection owningConnection, TaskCompletionSource`1 retry, DbConnectionOptions userOptions, DbConnectionInternal oldConnection, DbConnectionInternal& connection)
   at System.Data.ProviderBase.DbConnectionInternal.TryOpenConnectionInternal(DbConnection outerConnection, DbConnectionFactory connectionFactory, TaskCompletionSource`1 retry, DbConnectionOptions userOptions)
   at System.Data.ProviderBase.DbConnectionClosed.TryOpenConnection(DbConnection outerConnection, DbConnectionFactory connectionFactory, TaskCompletionSource`1 retry, DbConnectionOptions userOptions)
   at System.Data.ProviderBase.DbConnectionInternal.OpenConnection(DbConnection outerConnection, DbConnectionFactory connectionFactory)
   at System.Data.OleDb.OleDbConnection.Open()
   at ST_cc0028a4b56242909c2eae546a807995.csproj.ScriptMain.ImportFile(AccessFile file, DateTime startRecordDate, DateTime endRecordDate, List`1 accessTables, Boolean includeTransactionTables, List`1 specifiedTableList)
   at ST_cc0028a4b56242909c2eae546a807995.csproj.ScriptMain.Main()
End Error
Error: 2016-11-03 12:35:33.51
   Code: 0x00000006
   Source: Import Files 
   Description: The script returned a failure result.
End Error
Run Code Online (Sandbox Code Playgroud)

我确定的一些事情:

  • Access驱动程序已安装并在SQL Agent所在的服务器上运行.我通过在VS中运行包作为我的帐户和代理的帐户来验证这一点,没有任何问题.
  • 代理帐户可以访问相关文件.再次,通过以代理的帐户登录服务器进行验证.该文件位于网络共享上,但该路径指定为UNC路径.
  • 代理帐户可以访问属于此操作的其他数据库,以排除任何其他潜在的错误来源.
  • 从包存储(通过SSMS)运行包,因为我的帐户和代理的帐户都有效.我在数据库服务器上做了这个以确保.

在我在互联网上看到的其他问题中,这通常是司机的问题.在这种情况下,我不确定它是怎么回事.

我很乐意提供其他信息以帮助其他诊断.我自己完全不确定为什么这不起作用.

sir*_*ide 6

事实证明问题是Jet提供程序试图写入SQL Agent用户的临时目录,即使该任务是作为不同的用户模拟运行的.这似乎是Windows模拟系统的一项功能,它不会更改用户配置文件,只会更改用户令牌.我最终得到了这段代码:

var tempPath = Path.GetTempPath().Replace("\\SQLSERVERAGENT\\", "\\" + Environment.UserName + "\\");
Environment.SetEnvironmentVariable("TEMP", tempPath);
Environment.SetEnvironmentVariable("TMP", tempPath);
Run Code Online (Sandbox Code Playgroud)

它并不理想,但它有效.这意味着我不必为SQL Agent的临时目录授予权限.只有这个代码必须改变.

遗憾的是,似乎无法更改ODBC驱动程序放置其临时文件的位置.

编辑:我也有一个带有Excel源的常规基于数据流的包的问题.在这种情况下,我别无选择,只能为我的代理用户的帐户授予访问SQL Agent的临时目录的权限.如果我也可以在那里找到解决方法,我会发布它.