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



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

但现在我将它部署到Docker容器(使用mcr.microsoft/windows:1809-amd64(作为基础映像。我的dockerfile安装了.NET Core和AccessDatabaseEngine_X64.exe。但当我在容器上运行我的应用程序时,它会执行数百条"SQL"语句,但突然出现AccessViolationException。在反复运行相同的事务脚本后,我最终发现它总是在同一个查询上崩溃——并且该查询包含IsNull((。

我确认容器上的驱动程序文件与我的本地机器的文件匹配(均为64位(。为了进行测试,我在本地机器和容器上使用完全相同的数据库——但这并不重要,因为数据库可能是空的,从而导致访问冲突。

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

const string connectionString = @"Driver={Microsoft Access Driver (*.mdb, *.accdb)};Dbq=dbTest.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支持?

感谢

我收到访问冲突的原因是因为我需要安装Microsoft Access Runtime。Access数据库引擎和Microsoft Access运行时都是必需的——如果只安装了数据库引擎,则与MDB的连接可以工作,但您不能做任何花哨的事情。

现在,在Docker容器上正确安装Microsoft Access Runtime绝非易事。对于这个问题,有一个详细的答案:如何在Docker容器上安装Access Runtime?

我想补充一点,我不需要任何其他依赖项来实现端到端的工作。不是VC Runtime,也不是.NET Framework。

希望这对将来的其他人有所帮助。

最新更新