Autor Téma: delphi OCQCOQCOQO exception  (Přečteno 206 krát)

Offline PetrB0

  • Mladík
  • **
  • Příspěvků: 93
  • Karma: 1
    • Verze Delphi: Delphi XE2, Delphi 10.2 Tokyo, Delphi 10.41
delphi OCQCOQCOQO exception
« kdy: 26-03-2021, 14:02:53 »
Ahoj,
měl jsem přibližně následující kód (Delphi XE2, UniDac, Oracle DB)

Kód: Delphi [Vybrat]
  1. procedure TMujObject.ZpracujSQL
  2.  Begin
  3.   Try
  4.    ZiskejSQL;  //Odněkud "vydoluje" SQL a dá ho do proměné pSQL
  5.    ZpracujSQL_Telo   //Sem mi to skočí po výjimce
  6.   Finally
  7.   End;
  8.  End;
  9.  
  10. Procedure TMujObjectPotomek.ZpracujSQL_Telo
  11.  Begin
  12.    If Not Assigned(Q) Then
  13.     Q:=TUniQuery.Create(Nil);
  14.   Try
  15.     Q.SQL.Text:=pSQL;
  16.     Try
  17.      Q.Open;               //Při krokování se výjimka objeví zde
  18.      ZjistiParametery;  //Připraví si seznam parametrů
  19.      PrectiPole;  //Seznam polí dotazu
  20.     Except                 //Při běhu programu se zde po výjimce nezastaví, takže k logování nedojde
  21.      On E:Exception Do
  22.       Loguj(E);
  23.     End;
  24.  End;
  25.  

Celé to funguje i pokud je dotaz s parametry (které zde záměrně nijak nenastavuji). Ovšem když jsem měl v dotazu funkci "Trunc(:VKdy,'Year')" tak to padlo na výjimku, což bych akceptoval, ale nedojde k zachycení výjimky v rutině "_Telo", ale v její nadřazené rutině. Když se podívám do zásobníku při vzniku výjimky, tak tam vidím jako první čitelnou část právě to volání "ZpracujSQL_Telo" a za ním "TCustomDADataSet.SetActive") ne Q.Open.
Výjimky to dá konkrétně dvě. První je právě to OCQ... (tu hlásí GExpert Debugger Exception Notification) a druhá je že jsem předal špatný typ a namísto datumu je integer.
Logiku celého jsem opravil, takže v tom problém není (zjišťuji a nastavuji ty parametry dotazu jinde), ale zarazil mne ten styl výjimky. Proč to není chyceno u toho Q.Open (když krokuji, tak to zde skončí a ohlásí výjimky, ale vrátí mne to stejně do "ZpracujSQL")?
Při rozsáhlejším kódu se to celkem blbě hledá a docela mi trvalo, než jsem to přesné místo odhalil, protože těch potomků mám více, dělají různé věci a program zde proběhne x-krát.
Nevíte, k čemu by mohlo docházet (přepis části zásobníku?). Tuhle část programu jsem předělal, ale obecně mne to zajímá.

Díky

Pb
Díky

Pb

Offline vandrovnik

  • Guru
  • *****
  • Příspěvků: 1185
  • Karma: 51
    • Verze Delphi: 10.3
Re:delphi OCQCOQCOQO exception
« Odpověď #1 kdy: 26-03-2021, 14:15:18 »
A když dáš na řádek 22 breakpoint, zastaví se to na něm, nebo ne? Podle mne pokud dojde k výjimce na řádku 17, tak se řádek 22 musí vykonat.

Offline PetrB0

  • Mladík
  • **
  • Příspěvků: 93
  • Karma: 1
    • Verze Delphi: Delphi XE2, Delphi 10.2 Tokyo, Delphi 10.41
Re:delphi OCQCOQCOQO exception
« Odpověď #2 kdy: 26-03-2021, 17:13:25 »
Máš pravdu k tomu ošetření výjimky dojde, zaměnil jsem hlášku v logu s jinou.

Teď jsem se ještě jednou podíval na ten starý kód a když jsem vyházel věci za tím Q.Open a znovu to spustil, tak to doběhlo na to exception, ale při stisku break to poslušně skočilo na místo s chybou. Ale když tam ten kód vrátím, tak to zase při breaku skočí do metody, která tuto vyvolala. No nic. Asi to nechám a budu se věnovat upravenému řešení.

Jinak ten skutečný kód vypadá takto:
Kód: Delphi [Vybrat]
  1. procedure TZaznam.TestujSe;
  2. begin
  3.    if pStatusTestu=tstNic then
  4.     try
  5.      pStatusTestu:=tstProbiha;
  6.      VlastniTest;  //1-Tady
  7.     finally
  8.      pStatusTestu:=tstNic;
  9.     end;
  10. end;
  11.  
  12. //TSQLZaznam je potomkem TZaznam
  13. procedure TSQLZaznam.VlastniTest;
  14. Var
  15.    __Sl : TStringList;
  16. begin
  17.   inherited;
  18.  pDotaz.Close;
  19.  if SObsah='' then pStatusPolozky.ChybaFmt('Dotaz není definován',[])
  20.               Else
  21.                    Try
  22.                     pDotaz.SQL.Text:=SObsah;
  23.                     //Teď ježe zkus SQL parametry
  24.                     __Sl:=TStringList.Create;
  25.                     try
  26.                      ParametryZSQL(SObsah,__Sl);
  27.                      if not pZacatek then
  28.                       Begin
  29.                        Zjisti1(pParametry,__Sl,tzmtDeleteParam);
  30.                        Zjisti1(__Sl,pParametry,tzmtAddParam);
  31.                       End;
  32.                      pZacatek:=False;
  33.                      pParametry.Text:=__Sl.Text;
  34.                     finally
  35.                      __Sl.Free;
  36.                     end;
  37.  
  38.                    // ZjistiTypyParametru;
  39.  
  40.                     pDotaz.Open;  //Tady dojde k chybě
  41.                    {}                   //Když tuto část vypustím, tak mi break u exception ukáže skutečné místo chyby. Když ne, skočím na 1-Tady
  42.                     pTabulka.Open;
  43.                     //Zkus zjistit vypuštěná pole
  44.                     Zjisti(pTabulka,pDotaz,tzmtDeleteField);
  45.                     //Zkus zjistit nová pole
  46.                     Zjisti(pDotaz,pTabulka,tzmtAddField);
  47.  
  48.                     pTabulka.Assign(pDotaz);
  49.                     {}                 //Konec vypuštěné části
  50.                     pDotaz.Close;
  51.                    Except
  52.                     On E:Exception Do
  53.                      pStatusPolozky.ChybaFmt('V dotazu došlo k chybě "%s"',[E.Message]);
  54.                    End;
  55. end;
  56.  
  57.