ADO, ODBC - wykrycie zerwanego polaczenia

0

moj problem dotyczy c++buildera ale zapewne dla delphi jest takie samo rozwiazanie wiec napisalem tutaj.

sprawa wyglada tak:
lacze sie z baza postgres za pomoca ADO przez provider dla ODBC czyli ADO->ODBC->postgres.

przykladowy problem:

try
{
// tu wykonujemy jakies zapytanie, dowolne
}
catch(EOleException& ex)
{
// cos sie nie udalo wiec sprawdzamy co jest grane
ShowMessage(ex.ErrorCode);
}

w jaki sposob w bloku catch moge sprawdzic to ze zapytanie nie udalo sie bo np padl serwer bazy danych?
nie wazne jaki jest powod bledu (bledne,zapytanie,brak polacznie...) kod bledu zawsze jest taki sam i rowny -2147467259 co w opisie bledow OLE-DB oznacza blad niezdefiniowany. zawsze ten sam kod!
obsluga zdazen AfterDisconnect czy OnDisconnect nic nie da bo one dzialaja tylko wtedy gdy sam rozlacze baze. gdy to serwer padnie to zdarzenia te nie maja miejsca, malo tego gdy sprawdze stan obiektu polaczenia to wykazuje on ze polaczenie jest ciagle nawiazane.

w obiekcie wyjatku dostaje poprawny komunikat (np brak polaczenia, zle zapytanie itd) ale kod bledu jest ten sam. jak zatem moge sprawdzic ze winowajca jest zerwane polaczeni(np reset serwera) i ponowanie prubowac nawiazac polaczenie.
nie chec za kazdym wyjatkiem nawiazywac polaczenia na nowo bo w 90% przypadku nie bedzei takiej potzreby.

0
banita21 napisał(a)

...w obiekcie wyjatku dostaje poprawny komunikat (np brak polaczenia, zle zapytanie itd) ale kod bledu jest ten sam. jak zatem moge sprawdzic ze winowajca jest zerwane polaczeni(np reset serwera) i ponowanie prubowac nawiazac polaczenie...

No to sprawdzaj komunikat a nie kod (choć nie jest to najbardziej eleganckie z możliwych rozwiązań)

banita21 napisał(a)

nie chec za kazdym wyjatkiem nawiazywac polaczenia na nowo bo w 90% przypadku nie bedzei takiej potzreby.

Czyli w 90% przypadków będzie to błąd w SQL'u ? ;p

b

0

nie blad w zapytaniu ale np wysalnei blednych danych(data z wyprzedzeniem itd) wtedy baza weryfikuje bledne dane i zglasza wyjatek. tresc wyjaktu wszystko mowi ale kod jest ten sam. w takich sytuacjach nie moge sobie pozwolic na zerwanie i nawaizanie poalczenia(mam ku temu powody). po prostu chce wykryc ze blad jest wynikiem zerwanego polaczenia(nie kontrolowanego przeze mnie).

0

Zrobiłem to w mojej klasie TSQLManager. Jest w gotowcach dla Delphi. Ale nie będziesz miał problemów z przełożeniem tego na C++, bo to jest odczyt właściwie jednej właściwości.

0

musze cie zmartic.
w swojej klasie napisales:
const
E_CONNECTION_ERROR = -2147467259;

w obsludze wyjaktu sprawdzasz:
if AConnection.Errors.Item[i].Number = E_CONNECTION_ERROR then

i tu jest wlasnie ten problem o ktorym pisalem.
wartosc -2147467259 to nieokreslony blad! a nie blad poalczenia! bledy poalczenia to -2147217771 i -2147217770. niestety nie wazne jaki blad poleci to zawsze numer ustawia sie na -2147467259 czyli ten niezdefiniowany blad. dam glowe ze w twojej klasi blad wynikajacy np z blednej skladni sql jest uznany jako blad z polaczeniem.

0
banita21 napisał(a)

dam glowe ze w twojej klasi blad wynikajacy np z blednej skladni sql jest uznany jako blad z polaczeniem.

No właśnie nie. Fakt, że nie znalazłem tego błędu na stronach MS(jak i nie znalazłem żadnego w stylu ConnectionError), jednak błędna składnia SQL normalnie wywala się z komunikatem. W innym wypadku dostałbym przepełnienie stosu :)

0

tutaj masz spis z opisem mozliwych kodow bledow:
http://digital.ni.com/public.nsf/ad0f282819902a1986256f79005462b1/3bc28421b4761bcc8625710e006d76cb/
jedymy kod ktory sprawdzasz to blad niezdefiniowany.

w przypadku gdy polacznie jest takie: ADO->ODBC->PostgreSQL to ADO przy kazdym bledzie zglasza ten niezdefiniowany blad i z apomoca kodu bledu nie da sie rozgranicznyc co jest przyczyna.
jezli ty uzywales np bazy MSSQL i providera a nie ODBC to mozliwe ze efekt jest inny. jednak nie zmienia to faktu ze kod ktory porownujesz to nie jest kod bledu zerwanego poalczenia!

0

Faktycznie używam MSSQL. Provider to SQLOLEDB, ale sprawdzałem też zdaje się na SQLNativeClient.
Podczas pisania klasy zrobiłem test, że wyłączyłem serwer i się okazało, że to jedyny błąd jaki dostaję i nie było nic innego.

Może spróbuj jednego z tych(Z tego pliku, co podałeś):

0x80040E95  -2147217771  The provider could not connect to the server for
                            this object
0x80040E96  -2147217770  The provider could not connect to the server for
                            this object
0x80040E97  -2147217769  The attempt to bind to the object timed out

Tak przeleciałem przez te kody i wydaje mi się, ze mogą być najbardziej odpowiednie.

0

@Juhas: no przecież Ci pisze że zawsze ma ten sam kod. Zerkałem teraz jak to jest przy ADO - ODBC - FB i jest chyba tak samo.

@banita21: a dlaczego nie zadowolisz się tym komunikatem ? Z braku laku ... coś tam coś tam. Sprawdzaj występowanie określonego ciągu w komunikacie i podejmij decyzję czy robić reconnect.

b

0

dokladnei tak robie. prasuje sobie ten komunikat i podejmuje okreslone dzialanie. temat draze dalej poniewaz jak sam zauwazyles w pierwszej swojej wypowiedzi nie jest to najlepsze rozwiazanie:)

0

http://delphi.about.com/od/database/l/aa103001a.htm?p=1

Coś tam na dole pisze o jakiejść właściwości Error obiektu Connection. Może spróbuj tam zajrzeć, samemu mi się nie chce.

b

0

to jest tablica int ktora przechowuje ostatnie kody bledow czyli w moim przypadku zawsze ten sam:)

ADO nie jest dtworzone do pracy z ODBC a ze ma taka mozliwosc to inna bajka. Provide bazy danych dla OLE-DB(ado) musi dzialac wedlug jakiegos standardu i zapewne kazdy taki prowider zwraca kody bledow rozumiane przez ADO. ODBC ma swoje kody i zapewne sterownik ODBC do providera OLE-DB ODBC zwraca taki blod a samo ADO oczekuje bledu w "swoim" formacie a ze dostaje kod z ODBC to zawsze ustawia jako blod nieznany. tak wnioskuje ale nie jest to poparte dowodami:)

0

ADO działa najlepiej z MSSQL i MSAccess ... ciekawe dlaczego : )

1 użytkowników online, w tym zalogowanych: 0, gości: 1