[ kokolo2305 @ 09.04.2008. 22:39 ] @
Pozdrav da li mi neko moze objasniti na koji nacin izbjeci accesovu poruku o gresci kada pokusavam kroz formu da unesem vrijednost koja vec postoji u koloni koja je postavljena za primarni kljuc u bazi (kao sto je maticni broj itd) tj da mu se pojavi greska koju ja definisem.Pokusao sam sa try..except ali mi javi gresku i pored toga ponovo unese taj isti podatak u bazu..
Pored toga kako iskontrolisati cijelu kolonu prilikom unosa jer kada pokusam sa try..execpt samo kontrolise prvi zapis?
Hvala
[ savkic @ 09.04.2008. 23:40 ] @
> Pozdrav da li mi neko moze objasniti na koji nacin izbjeci accesovu poruku o gresci kada pokusavam kroz formu da unesem vrijednost koja vec
> postoji u koloni koja je postavljena za primarni kljuc u bazi (kao sto je maticni broj itd) tj da mu se pojavi greska koju ja definisem.
> Pokusao sam sa try..except ali mi javi gresku i pored toga ponovo unese taj isti podatak u bazu..

Šta znači ponovo unese isti podatak u bazu? Ako na polju postoji primarni ključ a novi slog ima istu vrednost kao i neki postojeći slog onda taj novi slog se neće upisati.

Obrada grešaka otprilike ovako izgleda:

Code:


try
  Query.ExecSql; // Konkretna sintaksa zavisi od dataset komponenti i načina rada.
except
  on E: EDatabaseError do   // Treba videti koja Exception klasa se podiže kod povrede referencijalnog integriteta i nju treba hendlovati
    ShowMessage('Greska');
end;



> Pored toga kako iskontrolisati cijelu kolonu prilikom unosa jer kada pokusam sa try..execpt samo kontrolise prvi zapis?

O kojoj kontroli pričaš, referencijalni integritet (jedinstvenost ključeva) će sprovesti baza, šta ti želiš da kontrolišeš?
[ kokolo2305 @ 10.04.2008. 06:33 ] @
Nakon sto sam postao poruku shvatio sam da je totalni višak drugi dio pitanja jer znam da ce referencijani integritet spriječiti ponovni unos..Znači povezao sam delphi sa accessovom bazom (klasicno adotable,microsoft jet ole 4.0 DBprovider itd).Ostaje samo "presretanje greške" pokušaću na način kako si opisao..
Inace javlja gresku da se stvara dupli unos zapisa koji je primarni ključ...
Hvala
[ X Files @ 10.04.2008. 06:57 ] @
Ze znam da li sam razumeo.

Kod C++ Buildera, a sigurno i u Delphiju postoje one OnPostError(), OnDeleteError(), itd, za svaki Query ili Table... Jedan od argumenata tih metoda je Action, koji kad se postavi na daAbort, ne javlja poruku o gresci, vec ostavlja programeru da odradi logiku, na osnovu onoga E.

Code:

void __fastcall TDM::GlavnaADOTablePostError(TDataSet *DataSet,
      EDatabaseError *E, TDataAction &Action)
{
   Action = daAbort;
   // ...
}

[ kokolo2305 @ 17.04.2008. 10:50 ] @
Uspjeo sam da handlujem gresku (bar se nadam da jesam) i tako kada se javi greska umjesto accesove ili delphijeve pojavljuje se poruka koju sma ja postavio, ali imam jednu malu smetnju a to je da kada treba da iskontrolise i nakon toga unese vrijednosti u bazu javi mi poruku o gresci ali istovremeno u dbgrid prikaze taj dupli podatak koji nebi smjeo. Ne upisuje ga u bazu ali ga prikazuje na dbgrid.. Kako bi se to moglo sprijeciti?
[ savkic @ 17.04.2008. 11:38 ] @
Verovatno si handlovanjem greske onemogućio exception mehanizam koji u normalnim okolnostima ne bi dozvolio upis sloga u lokalni dataset. Potrebno je da handlovanje uradiš tako da podigneš izuzetak (sa tvojim tekstom), da posle prikazivanja poruke pozoveš Abort ili da obrišeš slog iz memorijskog dataseta.
[ kokolo2305 @ 19.04.2008. 15:56 ] @
Presretanje greske sam obavio na sljedeci nacin pa molim vas ako neko ima prakticniji savjet tu sam da saslusam..
na dogadjaju OnPostError za moju adotable napisao sam sljedeće

Code:

adotable1.CancelUpdates;
showmessage('neka poruka');
 Action := daAbort;


i trenutno mi funkcionise (tj nepojavljuje se poruka od delphija niti se podatak upisuje u dbgrid )..izgleda mi malo "jeftino" rjesenje?!
[ Trodmi @ 20.04.2008. 12:41 ] @
Pozdrav,
Sva ta mucenja sa exception prljavstinom mozes zaobici na sledeci nacin:
Code:
 
 if not adotable1.Locate('Firstname',edit2.Text,[lopartialkey])
then showmessage('Not in database')
else showmessage('Record found') 

Umesto 'Firstname' stavi naziv tvoje kolone, tj : 'JMBG' ili kako si vec nazvao. Ako ga ima, izdaj poruku, ako ne, nastavi sa unosom.
Nadam se da je ovo barem malo pomoglo.
[ savkic @ 20.04.2008. 18:32 ] @
> Sva ta mucenja sa exception prljavstinom mozes zaobici na sledeci nacin:
> if not adotable1.Locate('Firstname',edit2.Text,[lopartialkey])

Ovakav pristup može biti nepouzdan kod istovremenog rada više korisnika, ako baza podržava referencijalni integritet treba ga koristiti. Handlovanje greške u OnPostError je u redu, s tim što ne preporučujem prikazivanje generičkog teksta (Unos nije uspeo). Treba staviti dovoljno informacija da se zna koja tabela je u pitanju i koji objekat (primarni, spoljni ključ, indeks), olakšava kasniju pomoć korisnicima.
[ kokolo2305 @ 20.04.2008. 19:17 ] @
pa normalno poruka ce se javiti u vidu 'Maticni broj koji pokusavate da unesete vec postoji' itd...jedno pitanje sta radi ,[lopartialkey] u ovom dijelu?
Code:
 if not adotable1.Locate('Firstname',edit2.Text,[lopartialkey])

gledao sam help kaze nesto kao omogucava prikaz vrijednosti koje nisu potpune..(u slucaju da se unese merc prikazat ce i vrijednosti kao mercedes itd..)
jeli to to?
[ X Files @ 20.04.2008. 19:30 ] @
Citat:
savkic:Handlovanje greške u OnPostError je u redu, s tim što ne preporučujem prikazivanje generičkog teksta (Unos nije uspeo). Treba staviti dovoljno informacija da se zna koja tabela je u pitanju i koji objekat (primarni, spoljni ključ, indeks), olakšava kasniju pomoć korisnicima.


Slažem se.

Kolekcija TADOConnection::Errors (nakon greške) u principu ima dovoljno podataka za informaciju korisniku šta se dogodilo.

Ali ipak, lično sam vremenom usvojio jedno možda ne baš najsrećnije rešenje sa stanovišta dobre prakse (jer tekst poruke nije obavezan da za sva vremena ostane onakav kakav je sada), ali ipak da ga pomenem. radi se o parsovanju E.Message.

// kod je Borland C++ Builder, ali je 100% VCL tako da ga necu prevoditi...
Code:

void __fastcall TDM::ManifestacijaADOTablePostError(TDataSet *DataSet,
      EDatabaseError *E, TDataAction &Action)
{
   Action = daAbort;

   // ***********************************************************************
   // PROVERA DA LI JE NESTO DUPLIRANO ...
   // ***********************************************************************
   if ( StrPos( E->Message.c_str(), "duplicate values" ) != NULL )
   {
      ShowMessage( "PODACI NISU IZMENJENI\n"
                   "Ne sme doći do dupliranja!" );
      return;
   }

   if ( StrPos( E->Message.c_str(), "duplicate key" ) != NULL )
   {
      ShowMessage( "PODACI NISU IZMENJENI\n"
                   "Ne sme doći do dupliranja manifestacije!" );
      return;
   }

   // ***********************************************************************
   // PROVERA DA LI SU POLJA PRAZNA ...
   // ***********************************************************************

   if ( StrPos( E->Message.c_str(), "zero-length"                  ) ||
        StrPos( E->Message.c_str(), "Null value"                   ) ||
        StrPos( E->Message.c_str(), "must have a value"            ) ||
        StrPos( E->Message.c_str(), "Error in row"                 ) ||
        StrPos( E->Message.c_str(), "not a valid date"             ) ||
        StrPos( E->Message.c_str(), "Datetime field overflow"      ) ||
        StrPos( E->Message.c_str(), "related record is required "  ) ||
        StrPos( E->Message.c_str(), "Empty row cannot be inserted" ) )
   {

      if ( StrPos( E->Message.c_str(), "Naziv" ) )
      {
         ShowMessage( "PODACI NISU IZMENJENI\n"
                      "Polje 'Naziv' ne može ostati prazno!" );
         return;
      }

      // ITD


      ShowMessage( "PODACI NISU IZMENJENI\n"
                   "Slog ne može biti prazan!\n\n" + E->Message );

      return;
   }

   // ***********************************************************************
   // AKO NIJE NI JEDNA OD PREDVIDJENIH GRESAKA ...
   // ***********************************************************************
   ShowMessage( "Nepoznata greska.\nMolimo zapišite je i javite Tehnickoj podršci.\n\n" + E->Message );
}