Results 1 to 12 of 12

Thread: Harde foutmeldingen netjes afhandelen

  1. #1
    John Kuiper
    Join Date
    Apr 2007
    Location
    Almere
    Posts
    8,747

    Harde foutmeldingen netjes afhandelen

    Hoe vertel ik aan mijn gebruikers op een nette manier dat de persoon niet verwijderd kan worden, omdat er nog een relatie is bij een een ander tabel. Als ik nu een persoon wil verwijderen, dan krijg ik een harde melding:
    An error occured while applying the updates in a record: IBConnection1 : Execute :
    -violation of FOREIGN KEY constraint "FK_INSCHRIJVINGEN_NAW" on table "INSCHRIJVINGEN"
    -Foreign key references are present for the record.

    Press OK to ignore and risk data corruption.
    Press Cancel to kill the program.
    Wat is er mis met een eigen melding :
    Deze persoon kan niet worden verwijderd, omdat hij/zij nog inschrijvingen in 1 van de shows hebben staan.
    ik gebruik: SQLDB met lazarus 1.62 / FPC 3.0 en firebird
    Delphi is great. Lazarus is more powerfull

  2. #2
    Je kunt deze exception gewoon zelf afvangen.
    In de On E: Exception kun je controleren op

    Exception EIBInterBaseError
    en EIBInterBaseError(E).IBErrorCode = 335544466

    Delphi Code:
    1. except
    2.   on E: EIBInterBaseError do
    3.     if EIBInterBaseError(E).IBErrorCode = 335544466 then
    4.     begin
    5.       Showmessage('Dit record wordt elders nog gebruikt. Verwijderen is niet mogelijk');
    6.     end;
    7. end;

    Edit:
    Kleine aanpassing voor Lazarus:
    Delphi Code:
    1. uses ibase40; // alleen voor de isc_foreign_key constant
    2. ...
    3. try
    4.   //
    5. except
    6.   on E: EIBDatabaseError do
    7.     if E.ErrorCode = isc_foreign_key {335544466} then
    8.     begin
    9.       Showmessage('Dit record wordt elders nog gebruikt. Verwijderen is niet mogelijk');
    10.     end;
    11. end;
    Last edited by rvk; 14-Feb-17 at 17:20.

  3. #3
    John Kuiper
    Join Date
    Apr 2007
    Location
    Almere
    Posts
    8,747
    dit werkt niet. Een delete in de dataset wordt uitgevoerd, waardoor er geen exception plaats vind. Daarna wordt er een update naar de database gestuurd. die geeft een foutmelding dat er een foreign key is, die de record niet mag verwijderen.
    Delphi is great. Lazarus is more powerfull

  4. #4
    Waar komt die melding "An error occured while applying the updates" dan vandaan? Dat is toch een exception? Die kun je toch afvangen?

    In ieder geval doe ik het bij mij zo, en indien een relatie, waar nog documenten aanhangen, verwijderd dreigt te worden, wordt deze exception prima afgevangen.

    Ps. als je bedoeld dat je de exception pas krijgt bij applyupdates moet je de exception natuurlijk daar afvangen met try/except maar ik dacht dat dat wel duidelijk was.

  5. #5
    mov rax,marcov; push rax marcov's Avatar
    Join Date
    Apr 2004
    Location
    Ehv, Nl
    Posts
    10,357
    en een rollback doen om eventueel uitgevoerde delen ongedaan te maken.

  6. #6
    Klinkt een beetje als de transaction valkuil bij Firebird.

    Hoe handel je je transacties af John?

  7. #7
    John Kuiper
    Join Date
    Apr 2007
    Location
    Almere
    Posts
    8,747
    Er is niet mis met de transacties, Benno.

    @rvk
    De applyupdate wordt uitgevoerd in de afterDelete van TSQLQuery. Als ik deze nu verplaatst naar de try execpt, zal het resultaat wel anders zijn (denk ik). Ga ik even testen en kom er op terug.
    Delphi is great. Lazarus is more powerfull

  8. #8
    Overigens John, je hebt in Lazarus SQLdb ook nog OnUpdateError() waar je de melding kunt geven.

    Dus je hebt twee plaatsen.
    Of de DoApplyUpdateError()
    Of daar waar je het commando Delete, de Post daarvan rond een try/except zetten.

    Delphi Code:
    1. procedure TForm1.DoApplyUpdateError(Sender: TObject; DataSet: TCustomBufDataset; E: EUpdateError;
    2.   UpdateKind: TUpdateKind; var Response: TResolverResponse);
    3. begin
    4.   ShowMessage('my error in ApplyUpdate');
    5.   Response := rrAbort;
    6. end;

  9. #9
    John Kuiper
    Join Date
    Apr 2007
    Location
    Almere
    Posts
    8,747
    Die had ik al getest, maar kreeg ik een sigdev
    Delphi is great. Lazarus is more powerfull

  10. #10
    Dan doe je waarschijnlijk ergens iets fout
    Alleen moeilijk voor ons te bepalen wat zonder code te zien.

    Bijgaand een test-projectje wat laat zien wat ik bedoel.
    Attached Files Attached Files

  11. #11
    John Kuiper
    Join Date
    Apr 2007
    Location
    Almere
    Posts
    8,747
    Ik heb het nu zo opgelost:
    Delphi Code:
    1. procedure TDMNAW.SQLnawAfterDelete(DataSet: TDataSet);
    2. var MyQuery : TSQLQuery;
    3. begin
    4.   try
    5.     MyQuery := TSQLQuery(dataset);
    6.     MyQuery.ApplyUpdates;
    7.     CommitQuery(DataSet)
    8.   except
    9.     showmessage('Persoon kan niet worden verwijderd, omdat deze nog is ingeschreven');
    10.   end;
    11. end;
    Normaal staat deze procedure gekoppeld aan een andere procedure, maar heb voor die tabel deze losgekoppeld.
    Dit werkt (ten dele). Een refresh werkt niet omdat op 1 of andere manier geen applyupdates is uitgevoerd. Do ik dat als nog, kom ik in een visuele cirkel, omdat de record is gelinkt aan een andere tabel d.m.v. foreign key.
    Delphi is great. Lazarus is more powerfull

  12. #12
    Marius
    Join Date
    Jul 2013
    Location
    Groningen
    Posts
    178
    Zomaar een opmerking; Bij een commitquery hoort wellicht een rollbackquery?

    Deze "kale" except zonder intelligentie afhandeling verdient niet de schoonheidsprijs.
    Wat als je een verplicht veld niet hebt ingevuld?
    Wat als er bij een insert een duplicate value ontstaat?

Thread Information

Users Browsing this Thread

There are currently 1 users browsing this thread. (0 members and 1 guests)

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •