Delphi-PRAXiS
Seite 1 von 4  1 23     Letzte »    

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Datenbanken (https://www.delphipraxis.net/15-datenbanken/)
-   -   Delphi Fehlermeldung beim Zugriff auf die Datenbank (https://www.delphipraxis.net/209812-fehlermeldung-beim-zugriff-auf-die-datenbank.html)

Humbucker 25. Jan 2022 16:14

Datenbank: Microsoft Access • Version: 2012 • Zugriff über: FireDAC

Fehlermeldung beim Zugriff auf die Datenbank
 
Liste der Anhänge anzeigen (Anzahl: 1)
Hallo zusammen,

seit der Umstellung unserer Anwendung auf FireDAC gibt es eine Fehlermeldung, welche nur in Verbindung mit einer Microsoft Access Datenbank auftaucht. Wird die Anwendung in Verbindung mit Microsoft SQLServer gestartet, tritt die Fehlermeldung nicht auf. Die betreffende Funktion wird vielfach durchlaufen und bringt die Fehlermeldung ausschließlich beim ersten Durchlauf. Zuvor wurden im Programmablauf bereits einige Daten ohne Probleme aus der Datenbank gelesen.

Die Fehlermeldung löst keine Exception aus und der Code wird mit dem nächsten Befehl fortgesetzt.:gruebel:

Fehlermeldung: "Abfrageunterstützung nicht verfügbar"

Delphi-Quellcode:
function GetFeldwertFromID(aTabelle, aFeld: string; aID: integer): Variant;
var
  MyQuery: TFDQuery;
begin
  if aID = 0 then
    exit;
  MyQuery := TFDQuery.Create(MyDB);
  MyQuery.Connection := MyDB;
  with MyQuery do
  begin
    if FindField('GELOESCHT') <> Nil then
      SQL.Text := ' Select ' + aFeld + ' from ' + aTabelle + ' where ID = ' + aID.ToString +
                  ' and GELOESCHT = 0 '
    else
      SQL.Text := ' Select ' + aFeld + ' from ' + aTabelle + ' where ID = ' + aID.ToString;
    try
      open; //--> hier tritt der Fehler auf
      first;
      if (FieldByName(aFeld).AsString = '') or (FieldByName(aFeld).IsNull) or
        (Recordcount = 0) then
        Result := StrKeinEintrag
      else
        Result := FieldByName(aFeld).AsString;
    finally
      Close;
      Free;
    end;
  end;
end;
Meine Recherche in Google und hier im Forum waren erfolglos. Hat jemand eine Idee was das sein könnte?
Danke für euere Ideen.

VG Michael

Union 25. Jan 2022 16:54

AW: Fehlermeldung beim Zugriff auf die Datenbank
 
Welchen ODBC Treiber verwendest Du?

BerndS 25. Jan 2022 17:10

AW: Fehlermeldung beim Zugriff auf die Datenbank
 
Das hat zwar nichts mit der Fehlermeldung zu tun, aber FindField auf eine geschossene Query ohne Sql sollte doch immer nil sein.
Weiterhin sollte nach
Delphi-Quellcode:
   MyQuery := TFDQuery.Create(MyDB);
ein try folgen sonst bleibt die MyQuery bei einer Exception beim Open im Speicher.

Delphi-Quellcode:
function GetFeldwertFromID(aTabelle, aFeld: string; aID: integer): Variant;
var
  MyQuery: TFDQuery;
begin
  if aID = 0 then
    exit;
  MyQuery := TFDQuery.Create(MyDB);
  try
    MyQuery.Connection := MyDB;
    with MyQuery do
    begin
      ...
      try
        open; //--> hier tritt der Fehler auf
        first;
        if (FieldByName(aFeld).AsString = '') or (FieldByName(aFeld).IsNull) or
          (Recordcount = 0) then
          Result := StrKeinEintrag
        else
          Result := FieldByName(aFeld).AsString;
      finally
        Close;
      end;
    end;
  finally
    MyQuery.Free;
  end;
end;

himitsu 25. Jan 2022 17:35

AW: Fehlermeldung beim Zugriff auf die Datenbank
 
Nicht immer ... man könnte die Fields auch vorher erstellt haben. (was hier aber nicht gemacht wird, also Ja, ist immer Nil)


Zitat:

Delphi-Quellcode:
if (FieldByName(aFeld).AsString = '') or (FieldByName(aFeld).IsNull) or
        (Recordcount = 0) then

Delphi-Quellcode:
if FieldByName(aFeld).AsString = '' then
oder
Delphi-Quellcode:
if FieldByName(aFeld).AsString.IsEmpty then

Bei NULL liefert AsString immer einen LeerString und auch bei RecordCount=0 ist es NULL (also '').

Manche Datenbankkomponenten haben eigene TFields, wo es direkt ein IsEmpty oder IsEmptyOrNull gibt (für String-Fields also bei NULL oder '' )
Delphi-Quellcode:
if FieldByName(aFeld).IsEmpty then

Sinspin 26. Jan 2022 06:47

AW: Fehlermeldung beim Zugriff auf die Datenbank
 
Und wieder mal ein
Delphi-Quellcode:
with
und keiner sagt was. :roll: Das ist eine Art von Schreibfaulheit die früher oder später zu sehr schönen Fehlern führen wird.

Schau mal nach was in dem Fall in aFeld und aTabelle steht.
Ich denke aber es liegt daran :
Delphi-Quellcode:
aID.ToString
. Ändere das mal um in
Delphi-Quellcode:
IntToStr(aID.AsInteger)
Wenn aID NULL ist bleibt der String leer und die Abfrage ist fehlerhaft.

Klaus01 26. Jan 2022 07:34

AW: Fehlermeldung beim Zugriff auf die Datenbank
 
aId kann eigentlich, da es als Parameter der Funtione deklariert ist, nicht "null" sein.

versuche es mal so:

Delphi-Quellcode:
function GetFeldwertFromID(aTabelle, aFeld: string; aID: integer = 0): Variant;
var
  MyQuery: TFDQuery;
begin
  if aID = 0 then
    exit;
  MyQuery := TFDQuery.Create(nil);
  try
    myQuery.Connection := myDb;
    if myQuery.Connection.Connected then
    begin
      if myQuery.FindField('GELOESCHT') <> Nil then
        myQuery.SQL.Text := 'Select :aFeld from &aTabelle where ID = :aID '+
                    ' and GELOESCHT = 0 '
      else
        myQuery.SQL.Text := 'Select :aFeld from &aTabelle where ID = :aID ';

      myQuery.ParamByName('aFeld').AsString := aFeld;
      //myQuery.ParamByName('aTabelle').AsString := aTabelle;
      myQuery.MacroByName('aTabelle').AsString := aTabelle;
      myQuery.ParamByName('aId').AsInteger := aId;
      try
        myQuery.Open; //--> hier tritt der Fehler auf
        if myQuery.Recordcount = 0 then
          Result := 'Kein Eintrag'
        else
          Result := myQuery.FieldByName(aFeld).AsString;
      except
        raise;
      end;
    end;
  finally
    myQuery.Close;
    myQuery.Free;
  end;
end;
Grüße
Klaus

Frickler 26. Jan 2022 08:11

AW: Fehlermeldung beim Zugriff auf die Datenbank
 
Zitat:

Zitat von Klaus01 (Beitrag 1501197)
Code:
'Select :aFeld from :aTabelle where ID = :aID '

Das dürfte so nicht gehen. Der Tabellenname kann kein Parameter sein, wohl aber ein Macro:
Code:
'Select :aFeld from &aTabelle where ID = :aID '
und dann
Code:
myQuery.MacroByName('aTabelle').AsString := aTabelle;

Klaus01 26. Jan 2022 08:17

AW: Fehlermeldung beim Zugriff auf die Datenbank
 
Zitat:

Zitat von Frickler (Beitrag 1501198)
Zitat:

Zitat von Klaus01 (Beitrag 1501197)
Code:
'Select :aFeld from :aTabelle where ID = :aID '

Das dürfte so nicht gehen.

danke - habe es im Beispiel ausgebessert.

himitsu 26. Jan 2022 12:33

AW: Fehlermeldung beim Zugriff auf die Datenbank
 
Zitat:

Delphi-Quellcode:
if aID = 0 then
  exit;

Exit, ohne vorher das Result zu initialisieren ... selbst Schuld, wenn es hier mal ein Problem gibt.
(dein Pech, dass die entsprechende Compilerwarnung für gemagte Typen leider nicht kommt)

Beispiel: rufe deine Funktion zwei Mal hintereinander auf, oder in einer Schleife ... dann wirst du viel Spaß haben.


Vorher abfragen, ob es das Feld gibt
Delphi-Quellcode:
if myDb.Connected and (aID <> 0) then
begin
  MyQuery := TFDQuery.Create(nil);
  try
    myQuery.Connection := myDb;

    myQuery.SQL.Text := 'select * from &aTabelle limit 0';
    myQuery.MacroByName('aTabelle').Value := aTabelle;
    myQuery.Open;
    if myQuery.FindField('GELOESCHT') <> nil then
      myQuery.SQL.Text := 'select :aFeld from &aTabelle where ID = :aID '
                        + ' and GELOESCHT = 0 '
    else
      myQuery.SQL.Text := 'select :aFeld from &aTabelle where ID = :aID ';
    myQuery.Close;

    myQuery.ParamByName('aFeld').AsString := aFeld;
    myQuery.MacroByName('aTabelle').Value := aTabelle;
    myQuery.ParamByName('aId').AsInteger := aId;
    myQuery.Open;
    Result := myQuery.FieldByName(aFeld).Value;
  finally
    myQuery.Free;
  end;
end
else
  Exit(Null);
oder nachher dessen Wert prüfen, wenn es das Feld gibt
Delphi-Quellcode:
Result := Null;
if myDb.Connected and (aID <> 0) then
begin
  MyQuery := TFDQuery.Create(nil);
  try
    myQuery.Connection := myDb;
    myQuery.SQL.Text := 'select * from &aTabelle where ID = :aID ';
    myQuery.ParamByName('aFeld').AsString := aFeld;
    myQuery.MacroByName('aTabelle').Value := aTabelle;
    myQuery.ParamByName('aId').AsInteger := aId;
    myQuery.Open;
    if (myQuery.FindField('GELOESCHT') <> nil) and (myQuery.FieldByName('GELOESCHT').AsInteger = 0) then
      Result := myQuery.FieldByName(aFeld).Value;
  finally
    myQuery.Free;
  end;
end;
oder falls es Gelöscht und Nicht-Gelöscht gleichzeitig geben kann
Delphi-Quellcode:
    myQuery.Open;
    if (myQuery.FindField('GELOESCHT') = nil) or myQuery.Locate('GELOESCHT', 0, []) then
      Result := myQuery.FieldByName(aFeld).Value;
  finally

Humbucker 3. Feb 2022 09:46

AW: Fehlermeldung beim Zugriff auf die Datenbank
 
Hallo Bernd,

danke für die Nachricht.

Zitat:

Zitat von BerndS (Beitrag 1501186)
Das hat zwar nichts mit der Fehlermeldung zu tun, aber FindField auf eine geschossene Query ohne Sql sollte doch immer nil sein.

tatsächlich: Ich habe zu viel an der Routine geschraubt: Die Abfrage auf FindField wird immer NIL sein, da zuvor die Query nicht aktiv wurde. -> Ändert aber leider nichts an der Fehlersituation, da in jedem Fall ein SQL.Text zugewiesen wird und der darauf folgende Open (einmalig) die Exeption wirft.

Zitat:

Zitat von BerndS (Beitrag 1501186)
Weiterhin sollte nach
Delphi-Quellcode:
   MyQuery := TFDQuery.Create(MyDB);
ein try folgen sonst bleibt die MyQuery bei einer Exception beim Open im Speicher.

Ich vermute dein Kommentar bezieht sich mehr auf das Finally, wodurch ein auftretender Fehler im Stack bleibt. Auch diese Anregung nehme ich gerne auf. Vielen Dank.

Gruß Michael


Alle Zeitangaben in WEZ +1. Es ist jetzt 16:58 Uhr.
Seite 1 von 4  1 23     Letzte »    

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