使用Access SQL函数时,Microsoft Access ODBC驱动程序导致访问冲突

问题描述 投票:0回答:1

我正在本地计算机上使用Microsoft Access ODBC驱动程序(由AccessDatabaseEngine_X64.exe安装)在较旧的Access数据库上运行“ SQL”语句。这里一切正常。

但是现在我将其作为基本映像部署到Docker容器(使用mcr.microsoft.com/windows:1809-amd64)。我的dockerfile安装了.NET Core以及AccessDatabaseEngine_X64.exe。但是,当我在容器上运行我的应用程序时,它会很好地执行数百个“ SQL”语句,但随后突然出现AccessViolationException。一遍又一遍地运行相同的事务脚本后,我最终发现它始终在同一查询上崩溃-并且该查询包含IsNull()。

我确认容器上的驱动程序文件与我的本地计算机的驱动程序文件匹配(均为64位)。为了进行测试,我在本地计算机和容器上使用了完全相同的数据库-但这并不重要,因为该数据库可以为空以获取访问冲突。

我将测试应用程序简化为这个简单的程序:

const string connectionString = @"Driver={Microsoft Access Driver (*.mdb, *.accdb)};Dbq=db\Test.mdb";
const string sql = "SELECT IsNull(null)";
var odbcConnection = new OdbcConnection(connectionString);
odbcConnection.Open();
odbcConnection.Execute(sql); // Dapper

在我的本地计算机上,它可以正常工作,但是在容器中,这会因AccessViolationException而崩溃。这是容器输出中的异常:

Fatal error. System.AccessViolationException: Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
   at Interop+Odbc.SQLExecDirectW(System.Data.Odbc.OdbcStatementHandle, System.String, Int32)
   at Interop+Odbc.SQLExecDirectW(System.Data.Odbc.OdbcStatementHandle, System.String, Int32)
   at System.Data.Odbc.OdbcStatementHandle.ExecuteDirect(System.String)
   at System.Data.Odbc.OdbcCommand.ExecuteReaderObject(System.Data.CommandBehavior, System.String, Boolean, System.Object[], SQL_API)
   at System.Data.Odbc.OdbcCommand.ExecuteReaderObject(System.Data.CommandBehavior, System.String, Boolean)
   at System.Data.Odbc.OdbcCommand.ExecuteNonQuery()
   at Dapper.SqlMapper.ExecuteCommand(System.Data.IDbConnection, Dapper.CommandDefinition ByRef, System.Action`2<System.Data.IDbCommand,System.Object>)
   at Dapper.SqlMapper.ExecuteImpl(System.Data.IDbConnection, Dapper.CommandDefinition ByRef)
   at Dapper.SqlMapper.Execute(System.Data.IDbConnection, System.String, System.Object, System.Data.IDbTransaction, System.Nullable`1<Int32>, System.Nullable`1<System.Data.CommandType>)

[我想澄清一下,我正在容器上运行数百个其他查询,但是当IsNull()在命令文本中的任何位置时,它总是失败。

所以我很好奇,尝试了其他一些Microsoft Access函数,例如Now()和IsNumeric(1030)。那些也抛出AccessViolationException!

我真的在为如何继续解决这个问题而苦苦挣扎。为什么驾驶员的行为有所不同?驱动程序不支持Microsoft Access功能,或者是否需要添加依赖项以获得完整的Microsoft Access支持?

谢谢

ms-access odbc
1个回答
1
投票

之所以得到访问冲突,是因为我需要安装Microsoft Access Runtime。 Access Database Engine和Microsoft Access Runtime都是必需的-如果仅安装了数据库引擎,则与MDB的连接可以工作,但您无法做任何花哨的事情。

现在在Docker容器上正确安装Microsoft Access Runtime并不是一件容易的事。为此,对此问题有一个详细的答案:How to install Access Runtime on a Docker container?

我想补充一点,我不需要任何其他依赖关系就能使它端到端地工作。不是VC Runtime,不是.NET Framework。

希望这对以后的人有所帮助。

© www.soinside.com 2019 - 2024. All rights reserved.