Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Datenbanken (https://www.delphipraxis.net/15-datenbanken/)
-   -   Delphi locate vor insert (https://www.delphipraxis.net/107549-locate-vor-insert.html)

Delphi-Phil 29. Jan 2008 17:00

Datenbank: mysql • Zugriff über: ado

locate vor insert
 
Hallo,
ich hätte da mal folgende Frage an alle Datenbank Experten...

Mit dieser Prozedur wird eine Neue Klasse in meiner Tabelle angelegt, jetzt würde ich gerne prüfen ob die klasse schon vorhanden ist und wenn ja eine Meldung ausgeben. Würdet ihr das mit Table.Locate machen oder wie macht man das am besten??

Delphi-Quellcode:
procedure THauptForm.Klasse1Click(Sender: TObject);
var
  Klasse : String;
begin
  Klasse := InputBox('Neue Klasse anlegen', 'Klasse:','');
  if Klasse <> '' then
  begin
    //Prüfen ob der eintrag nicht schon vorhanden ist!!
    TblKlassen.Insert;
    TblKlassen.FieldByName('Klassenname').AsString := Klasse;
    TblKlassen.Post;
    TblKlassen.First;
  end;
end;

Gruß Phil

Union 29. Jan 2008 17:24

Re: locate vor insert
 
Ja, das ginge folgendermassen (ungetestet):
Delphi-Quellcode:
procedure THauptForm.Klasse1Click(Sender: TObject);
var
  Klasse : String;
begin
  Klasse := InputBox('Neue Klasse anlegen', 'Klasse:','');
  if Klasse <> '' then
  begin
    //Prüfen ob der eintrag nicht schon vorhanden ist!! 
    if TblKlassen.Locate('Klassenname', Klasse, [loIgnoreCase]) then
      ShowMessage('Klasse schon vorhanden')
    else
    begin
      TblKlassen.Insert;
      TblKlassen.FieldByName('Klassenname').AsString := Klasse;
      TblKlassen.Post;
      TblKlassen.First;
    end;
  end;
end;
Falls das DataSet gross ist, sollte ein Index auf UpperCase(KlassenName) erstellt sein.

Delphi-Phil 29. Jan 2008 20:21

Re: locate vor insert
 
also es war schon richtig nur an einer kleinen Sache war noch ein Problemchen...


Es muss richtig so sein:
Delphi-Quellcode:
procedure THauptForm.Klasse1Click(Sender: TObject);
var
  Klasse : String;
begin
  Klasse := InputBox('Neue Klasse anlegen', 'Klasse:','');
  if Klasse <> '' then
 begin
    //Prüfen ob der eintrag nicht schon vorhanden ist!!
    if TblKlassen.Locate('Klassenname', Klasse, [b][loCaseInsensitive][/b]) then
      ShowMessage('Klasse schon vorhanden')
    else
    begin
      TblKlassen.Insert;
      TblKlassen.FieldByName('Klassenname').AsString := Klasse;
      TblKlassen.Post;
      TblKlassen.First;
    end;
  end;
end;
Gruß Phil und vielen Dank für Eure Hilfe!

hoika 30. Jan 2008 10:04

Re: locate vor insert
 
Hallo,

du könntest das auch über einen unique index lösen.
Das Post schlägt dann fehl

try
Table.Post;
except
// Fehler
on E: EDBEngineError ....
end;


Heiko

RavenIV 30. Jan 2008 10:19

Re: locate vor insert
 
Zitat:

Zitat von hoika
Hallo,

du könntest das auch über einen unique index lösen.
Das Post schlägt dann fehl

try
Table.Post;
except
// Fehler
on E: EDBEngineError ....
end;

Wobei wir wieder beim Thema unsinnige Verwendung von Exception sind.
In dem Beispiel mit dem Locate wird die Exception vermieden.
Bei Dir wird explizit eine Exception verursacht, wo keine nötig ist.

Frei nach dem Motto:
Ich schütte halt mal Benzin in den Tank das Autos -> try
Wenn es halt einen Dieselmotor hat, dann geht halt was kaputt -> Exception.
Dann kann ich das ja versuchen zu reparieren -> except: Tank reinigen, Motor austauschen

==> Holzhammermethode. #@§#@#$£

Jelly 30. Jan 2008 10:26

Re: locate vor insert
 
Zitat:

Zitat von RavenIV
Wobei wir wieder beim Thema unsinnige Verwendung von Exception sind.
In dem Beispiel mit dem Locate wird die Exception vermieden.
Bei Dir wird explizit eine Exception verursacht, wo keine nötig ist.

Doch, genau da ist eine Exception nötig, weil die Konsistenz der Daten in der DB gefährdet ist.

Ein Locate prüft nur lokal im Dataset. Wenn sich nach dem Öffnen der Tabelle an einer anderen Stelle ein Insert in die Klasse gemacht wird, so kriegt das Dataset das nicht mit. Locate findet nix, und es wird unter Umständen eine Klasse doppelt eingefügt. Deshalb ist eine Exception schon richtig.

:warn: ES IST IMMER ANGELEGENHEIT DER DATENBANK, DIE KONSISTENZ DER DATEN ZU GEWÄHRLEISTEN.

Glaub mir. Das erspart viele Fehler in späteren Phasen eines Projektes, und man sollte sich erst gar nicht angewöhnen, solche Probleme falsch anzugehen.

RavenIV 30. Jan 2008 10:35

Re: locate vor insert
 
[quote="Jelly"]
Zitat:

Zitat von RavenIV
Doch, genau da ist eine Exception nötig, weil die Konsistenz der Daten in der DB gefährdet ist.

Ein Locate prüft nur lokal im Dataset. Wenn sich nach dem Öffnen der Tabelle an einer anderen Stelle ein Insert in die Klasse gemacht wird, so kriegt das Dataset das nicht mit. Locate findet nix, und es wird unter Umständen eine Klasse doppelt eingefügt. Deshalb ist eine Exception schon richtig.

:warn: ES IST IMMER ANGELEGENHEIT DER DATENBANK, DIE KONSISTENZ DER DATEN ZU GEWÄHRLEISTEN.

Es ist schon richtig, dass dafür die DB zuständig ist.

Aber Exception = Ausnahme = unerwarteter Fehler
Und Exception <> Allheilmittel

Wenn ich einen Fehler vorhersehen kann und vorher abprüfen kann, dann verwende ich keine Exception.
Locate - Insert - Post - Commit.
Da kann mir doch kein anderer Insert dazwischen pfuschen.

hoika 30. Jan 2008 11:56

Re: locate vor insert
 
Hallo,

zwischen Locate und Post kann aber schon
ein anderer Client den gleichen Wert in die DB geschrieben haben.


Heiko

Jelly 30. Jan 2008 12:27

Re: locate vor insert
 
Zitat:

Zitat von RavenIV
Es ist schon richtig, dass dafür die DB zuständig ist.

Aber Exception = Ausnahme = unerwarteter Fehler

Es ist ein unerwarteter Fehler, wenn der Datensatz schon existiert. Zumindest seh ich das so, dass aus Client Sicht ein Einfügen des Records einen Fehler auslösen soll, wenn es auf Datenbankebene fehl schlägt... Warum Client-seitig etwas prüfen, wofür der Server zuständig ist.

RavenIV 30. Jan 2008 12:31

Re: locate vor insert
 
Zitat:

Zitat von Jelly
Es ist ein unerwarteter Fehler, wenn der Datensatz schon existiert. Zumindest seh ich das so, dass aus Client Sicht ein Einfügen des Records einen Fehler auslösen soll, wenn es auf Datenbankebene fehl schlägt... Warum Client-seitig etwas prüfen, wofür der Server zuständig ist.

So gesehen...
Dann ist es OK, hier eine Exception zu verwenden.
Ich lasse mich gerne belehren und bekehren.


Alle Zeitangaben in WEZ +1. Es ist jetzt 17:21 Uhr.
Seite 1 von 2  1 2      

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz