Moje pytanie w dziale Newbe http://4programmers.net/Forum/viewtopic.php?id=162955 od ponad tygodnia leży odłogiem, więc pozwalam sobie zamieścić pytanie tu, licząc, że światłe umysły wskażą mi kierunek ominięcia betonowej ściany, o którą aktualnie rozbijam głowę.
To jest przykład z książki "Delphi 2005 Adama Boducha (do tego miejsca wszystko działało OK).
Poniżej przedstawiam maksymalnie odchudzony kod, który równie skutecznie wywala błąd. Zainstalowałem MySQL v. 5.1.45, Delphi2009. Podgląd baz w mysqlcc wygląda normalnie, łączę się z nimi bez problemu.
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, WideStrings, DBXMySql, DB, SqlExpr, StdCtrls;
type
TForm1 = class(TForm)
SQLConnection1: TSQLConnection;
Button1: TButton;
ListBox1: TListBox;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
begin
SQLConnection1.GetTableNames(ListBox1.Items);
end;
end.
Błąd występuje w automatycznie dołączanym module DBXDynalink:
function TDBXDynalinkCommand.DerivedExecuteQuery: TDBXReader;
var
ReaderHandle: TDBXReaderHandle;
ByteReader: TDBXDynalinkByteReader;
begin
ReaderHandle := nil;
if FCommandHandle = nil then
Open;
// Cheaper than using the property access which will cause a parameter row
// to be allocated. Also allows delegate driver to delegate the ParameterRow.
//
if ((FParameters = nil) or (FParameters.Count = 0)) and (not isPrepared) then
CheckResult(FMethodTable.FDBXCommand_ExecuteImmediate(FCommandHandle, TDBXWideString(GetText), ReaderHandle))
else
CheckResult(FMethodTable.FDBXCommand_Execute(FCommandHandle, ReaderHandle)); <======= tu się wywala
if ReaderHandle = nil then
begin
Result := nil;
end else begin
ByteReader := TDBXDynalinkByteReader.Create(FDBXContext, ReaderHandle, FMethodTable);
Result := TDBXDynalinkReader.Create(FDBXContext, ReaderHandle, FMethodTable, ByteReader);
end;
end;
Analizując zamieszczone w książce obrazki zauważyłem, że w połączeniu TSQLConnection (rys.14.13) używana jest biblioteka LibraryName=dbexpmysql.dll, natomiast po wybraniu ConnectionName=MySQLConnection, podpowiadana jest dbexpmys.dll.
Błąd występuje w linii:
CheckResult(FMethodTable.FDBXCommand_Execute(FCommandHandle, ReaderHandle));
poniżej podaję odczytane wartości parametrów.
Zachowanie przy różnych kombinacjach active=true/false oraz po zmianie biblioteki jest następujące:
1. connected=true, dbxmysql.dll
Project1.exe raised exception class EAccesViolation with message:
'Acces violation at adress 00C4E89C in module 'dbxmys.dll. Read of adress 00000000'
wartości parametrów:
FCommandHandle=$C84160
ReaderHandle=nil
2. connected=false, dbxmysql.dll
Project1.exe raised exception class EAccesViolation with message:
'Acces violation at adress 00D7E89C in module 'dbxmys.dll. Read of adress 00000000'
wartości parametrów:
FCommandHandle=$DB4160
ReaderHandle=nil
3. connected=false, dbxmys.dll
Project1.exe raised exception class EAccesViolation with message:
'Acces violation at adress 00D7E89C in module 'dbxmys.dll. Read of adress 00000000'
wartości parametrów:
FCommandHandle=$DB4160
ReaderHandle=nil
4. connected=true, dbxmys.dll
Project1.exe raised exception class EAccesViolation with message:
'Acces violation at adress 00C4E89C in module 'dbxmys.dll. Read of adress 00000000'
wartości parametrów:
FCommandHandle=$C84160
ReaderHandle=nil
Jak więc widać, niezależnie od zadeklarowanej biblioteki, błąd sygnalizuje zawsze dbxmys.dll, również fakt odłączenia od bazy zmienia tylko adres.
Będę wdzięczny za wszelkie wskazówki. Wydaje mi się, że właśnie dbExpress jest technologią, której powinienem używać - ale na razie najbardziej podstawowe instrukcje nie chcą działać :(