Почему повторное подключение к базе данных Oracle через dbExpress вызывает нарушение прав доступа?

У меня есть приложение Delphi 2006, работающее в Windows 7, которое подключается к базе данных Oracle через dbExpress с помощью установки клиента Oracle 11. После первого подключения я могу запросить данные, и все работает как положено. Однако, когда я отключаюсь, а затем снова подключаюсь, я получаю следующую ошибку:

Exception EAccessViolation in module orageneric11.dll at 00450EB5. 
Access violation at address 048A0EB5 in module 'orageneric11.dll'.
Read of address 00000038

Это же приложение отлично работает в Windows XP с использованием установки клиента Oracle 10 (к сожалению, у меня нет тестовой установки с XP + Oracle 11 или Windows 7 + Oracle 10).

Я сократил проблему до следующего:

program OracleReconnectTest; 

{$APPTYPE CONSOLE} 

uses
  SysUtils,
  SqlExpr; 

var
  connection: TSQLConnection;

begin
  connection := TSQLConnection.Create( nil );
  connection.DriverName := 'Oracle';
  connection.LibraryName := 'dbxora30.dll';
  connection.VendorLib := 'oci.dll';
  connection.GetDriverFunc := 'getSQLDriverORACLE';
  connection.LoginPrompt := False;
  connection.Params.Text :=
    'DATABASE=TheDatabase' + #$D#$A +
    'USER_NAME=TheUser' + #$D#$A +
    'PASSWORD=ThePassword' + #$D#$A +
    'DECIMAL SEPARATOR=,'; 

  connection.Connected := True; 

  Writeln( 'Connected once, press ENTER to disconnect and reconnect' );
  Readln; 

  connection.Connected := False;
  connection.Connected := True; // <- access violation on Windows 7 + Oracle 11

  Writeln( 'Reconnected, press ENTER to exit' );
  Readln;
end.

Я полагаю, это исключает проблему с кодом моего приложения. Я просмотрел код dbExpress, поставляемый с Delphi, но не обнаружил ничего, что выглядело бы неправильно или объясняло бы это.

Поэтому я не смог найти ничего, что указывало бы на ошибку ни в dbExpress, ни в драйвере Oracle. Следовательно, я не знаю, следует ли сообщать об ошибке в Embarcadero и/или Oracle.

Версия orageneric11.dll — это 11.2.0.1, а dbxora30.dll — это версия 10.0.2151.25345.

Поскольку параллельная установка нескольких версий клиента вызывала проблемы, на рассматриваемой машине установлен только клиент 11. Используя Process Explorer, я убедился, что используются только библиотеки DLL от клиента 11.

Кто-нибудь еще сталкивался с этой проблемой и может указать мне правильное направление?


person PersonalNexus    schedule 23.10.2012    source источник
comment
Можно ли подключаться/отключаться несколько раз во время разработки? К сожалению, я получаю исключение Uknown driver: Oracle, когда копирует/вставляет ваш пример выше и не имеет времени на расследование. Но я могу подключаться/отключаться несколько раз во время разработки, и я подключаюсь к базе данных Oracle 11g с клиентом 11. Мои DLL той же версии, что и ваша.   -  person Jason    schedule 24.10.2012
comment
Ok. Добавлен Data.DBXOracle в предложение использования, и он работает правильно. Мне удалось повторно подключиться успешно. У вас установлен только 11 клиент? У нас есть проблемы с добавлением, когда мы запускали клиент 9, поэтому порядок путей был важен.   -  person Jason    schedule 24.10.2012
comment
@Jason Установлен только клиент 11 (уточнил это в моем вопросе). Я проверю, смогу ли я повторно подключиться во время разработки, когда доберусь до офиса.   -  person PersonalNexus    schedule 24.10.2012
comment
@Jason Такое же нарушение прав доступа при подключении и отключении во время разработки.   -  person PersonalNexus    schedule 24.10.2012
comment
Прости. Тогда не уверен. Какую версию Делфи вы используете? Мой был с XE2 и Delphi 6. Оба работают нормально. Может, переустановить клиент?   -  person Jason    schedule 25.10.2012


Ответы (1)


Извините, у меня нет «красивого и приятного» решения, которое бы это исправило, но есть несколько вариантов, которые вы можете рассмотреть:

а) Смените используемый драйвер и попробуйте получить доступ к базе данных через ODBC после настройки ODBC DSN на клиенте для указанной базы данных. Драйвер с открытым исходным кодом можно найти здесь: https://sourceforge.net/projects/open-dbexpress/

б) Купите новую версию Delphi. Это может быть настоящей болью, я знаю. Это будет стоить денег и времени (больше, если задействованы сторонние компоненты), но иногда просто не лучшая идея использовать продукты, которым более десяти лет. С тех пор компания и интеллектуальная собственность, стоящая за Delphi, несколько раз трансформировались и продавались разным компаниям. Нет абсолютно никаких шансов получить официальную поддержку для этого устаревшего продукта.

c) (действительно некрасиво, но может иметь шанс): Создайте механизм пула, чтобы предотвратить закрытие соединения. Звучит действительно смешно, не так ли?

person Udontknow    schedule 17.11.2016
comment
Я действительно пошел с вариантом c). Не красиво, но работает. a) было невозможно, потому что усилия по поддержанию источников данных ODBC на каждом клиентском и серверном компьютере были исключены. И поэтому тратит деньги на более новую версию Delphi для варианта б). - person PersonalNexus; 19.11.2016
comment
Что вы делаете, когда вам нужно закрыть соединение? (например, пользователь меняет пароль, который использует соединение) Если вы освобождаете и создаете новый объект соединения, вы все еще получаете ту же ошибку AV? - person Paul McCarthy; 20.12.2016