22.08.2020, Vladimír Klaus, navštíveno 1202x
Pokud v Delphi pracujete s databázovými tabulkami, není od věci se tu a tam ujistit o tom, zda je požadovaná tabulka skutečně otevřena, aby nedošlo k chybě. Tedy něco jako:
if MyTable.Active then ...;
Na tom není opravdu nic zásadního, ovšem jen do té doby, kdy následující kód spadne v části "Lookup". A to na naprosto nesmyslnou EOleException chybu:
Operace není povolena, pokud je objekt uzavřen.
Operation is not allowed when the object is closed.
if MyTable.Active then begin
if MyTable.Lookup('Hodnota', AValue, 'ID') ...
end;
Takže tabulka je aktivní/otevřená, ale při hledání mi to nahlásí, že je zavřená. Šílené! Další vykonání kódu pak dokonce může vést k "Stack overflow."
Vzhledem k tomu, že podobné principy používám již mnoho let a bez problémů, bylo pátrání docela zdlouhavé a nalezené články a různé návrhy nikam nevedly.
Nakonec jsem vyzkoušel použít test na ADOConnection.Connected místo ADOTable.Active a světe div se, zabralo to!
Co jsem tedy dělal a proč nechápu, že toto zabralo? Tedy vypnu připojení (tím se má odpojit i tabulka!), změním připojení třeba k jiné databázi, připojím se a následně otevřu i tabulku. Zkrátka nic podivného.
ADOConnection.Connected:=false;
ADOConnection.ConnectionString:='...';
ADOConnection.Connected:=true;
MyTable.Open;
Zádrhel byl asi v tom, že mezi odpojením připojení ADOConnection a následným zavřením tabulky je jistá prodleva, během které se tabulka tváří jako otevřená (což možná interně i může být), ale už není připojená k databázi a jakékoliv použití, které vyžaduje dotaz do databáze, selže.
A protože moje výše uvedené hledání v tabulce bylo použito v cizí komponentě, které zřejmě volá tuto metodu velmi často nebo na základě nějakých podnětů mimo moji kontrolu (možná i paralelně), docházelo k tomuto průšvihu.
Zatím se zdá jako nejjistější toto řešení:
if ADOConnection.Connected and MyTable.Active then begin
if MyTable.Lookup('Hodnota', AValue, 'ID') ...
end;
Kdo nebo co může být na vině, když se to dříve nestávalo:
- Novější Delphi 10.4 místo 10.3
- Novější Microsoft OLE DB Driver for SQL Server 18.4 místo 18.3
- Novější DevExpress komponenty
- Případně něco dalšího, co není na první pohled zřejmé (aktualizace Windows apod.)