Драйвер Microsoft Access ODB C вызывает нарушение прав доступа при использовании функций Access SQL - PullRequest
0 голосов
/ 24 февраля 2020

Я использую драйвер Microsoft Access ODB C (установленный AccessDatabaseEngine_X64.exe) на локальном компьютере для запуска операторов "SQL" в более старой базе данных Access. Здесь все отлично работает.

Но теперь я развернул его в 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 () находится где-нибудь в команде text.

Поэтому мне было любопытно, и я попробовал некоторые другие функции Microsoft Access, такие как Now () и IsNumeri c (1030). Они также генерируют AccessViolationException!

Я действительно борюсь с тем, как продолжать решать эту проблему. Почему водитель ведет себя по-другому? Драйвер не поддерживает функции Microsoft Access, или мне нужно добавить зависимость, чтобы получить полную поддержку Microsoft Access?

Спасибо

1 Ответ

1 голос
/ 25 февраля 2020

Причина, по которой я получил нарушение прав доступа, заключается в том, что мне нужно было установить Microsoft Access Runtime. Оба Access Engine Engine и Microsoft Access Runtime оба необходимы - если только ядро ​​базы данных установлено соединения с работой MDB, но вы не можете делать ничего причудливого.

Теперь правильно установить Microsoft Access Runtime на Docker Контейнер был не маленьким подвигом. Для этого есть подробный ответ на этот вопрос: Как установить Access Runtime на Docker контейнер?

Я хочу добавить, что мне не нужны никакие другие зависимости для получения это работать сквозной. Не V C Runtime, а не. NET Framework.

Надеюсь, это поможет кому-то еще в будущем.

...