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:
Meine Recherche in Google und hier im Forum waren erfolglos. Hat jemand eine Idee was das sein könnte?
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; Danke für euere Ideen. VG Michael |
AW: Fehlermeldung beim Zugriff auf die Datenbank
Welchen ODBC Treiber verwendest Du?
|
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:
ein try folgen sonst bleibt die MyQuery bei einer Exception beim Open im Speicher.
MyQuery := TFDQuery.Create(MyDB);
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; |
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:
oder
if FieldByName(aFeld).AsString = '' then
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
|
AW: Fehlermeldung beim Zugriff auf die Datenbank
Und wieder mal ein
Delphi-Quellcode:
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.
with
Schau mal nach was in dem Fall in aFeld und aTabelle steht. Ich denke aber es liegt daran :
Delphi-Quellcode:
. Ändere das mal um in
aID.ToString
Delphi-Quellcode:
Wenn aID NULL ist bleibt der String leer und die Abfrage ist fehlerhaft.
IntToStr(aID.AsInteger)
|
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:
Grüße
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; Klaus |
AW: Fehlermeldung beim Zugriff auf die Datenbank
Zitat:
Code:
und dann
'Select :aFeld from &aTabelle where ID = :aID '
Code:
myQuery.MacroByName('aTabelle').AsString := aTabelle;
|
AW: Fehlermeldung beim Zugriff auf die Datenbank
Zitat:
|
AW: Fehlermeldung beim Zugriff auf die Datenbank
Zitat:
(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:
oder nachher dessen Wert prüfen, wenn es das Feld gibt
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);
Delphi-Quellcode:
oder falls es Gelöscht und Nicht-Gelöscht gleichzeitig geben kann
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;
Delphi-Quellcode:
myQuery.Open;
if (myQuery.FindField('GELOESCHT') = nil) or myQuery.Locate('GELOESCHT', 0, []) then Result := myQuery.FieldByName(aFeld).Value; finally |
AW: Fehlermeldung beim Zugriff auf die Datenbank
Hallo Bernd,
danke für die Nachricht. Zitat:
Zitat:
Gruß Michael |
AW: Fehlermeldung beim Zugriff auf die Datenbank
Zitat:
Delphi-Quellcode:
Database.DriverID := 'MSAcc';
|
AW: Fehlermeldung beim Zugriff auf die Datenbank
Zitat:
ist es sinnvoll die Änderung so
Delphi-Quellcode:
Ist .IsEmpty = True, auch wenn Recordcount gleich 0 oder das Feld nicht vorhanden ist? Wenn das Feld nicht vorhanden ist, sollte doch eine Exception ausgelöst werden.
if (FieldByName(aFeld).asString.IsEmpty) or (FieldByName(aFeld).IsNull) or
(Recordcount = 0) then oder so if FieldByName(aFeld).asString.IsEmpty then Danke für deine Antwort. Gruß Michael |
AW: Fehlermeldung beim Zugriff auf die Datenbank
Zitat:
warum geht das so nicht? Ich habe versucht mich in der Lektüre von Carry Jensen - Delphi in Depth: FireDAC zu diesem Thema einzulesen. Ich habe grundsätzlich verstanden, dass mit &MACRO eine Ersetzung im SQL-Statement stattfinden kann, die aber doch auch mit : PARAM (so wie in deinem ersten Beispiel) erfolgen kann. Ich verstehe den Unterschied zwischen den Ersetzungsbegriffen aTabelle und aFeld nicht, da es sich in beiden Fällen um Stringwerte handelt. Danke für deine Antwort. Gruß Michael |
AW: Fehlermeldung beim Zugriff auf die Datenbank
[QUOTE=himitsu;1501211]
Zitat:
Gruß Michael |
AW: Fehlermeldung beim Zugriff auf die Datenbank
Hallo Forum,
dank eurer vielen Kommentare und Anregungen habe ich den Code nun folgendermaßen angepasst:
Delphi-Quellcode:
Die ursprüngliche Fehlermeldung aus #1 bleibt aber weiterhin bestehen. Wie gesagt, die Fehlermeldung kommt nur in Verbindung mit einer Microsoft Access Datenbank und auch nur einmal beim ersten Druchlauf.
function GetFeldwertFromID(aTabelle, aFeld: string; aID: integer): Variant;
var MyQuery: TFDQuery; begin Result := StrKeinEintrag; MyQuery := TFDQuery.Create(MyDB); try MyQuery.Connection := MyDB; if (MyQuery.Connection.Connected) and (aID > 0) then begin with MyQuery do begin SQL.Text := 'select * from &pTabelle where ID = :pID'; MacroByName('pTabelle').asRaw := aTabelle; ParamByName('pId').asInteger := aId; try open; if not (FieldByName(aFeld).IsNull) and not (FieldByName(aFeld).asString.IsEmpty) and (Recordcount > 0) and ((FindField('GELOESCHT') = nil) or (Locate('GELOESCHT', 0, []))) then Result := FieldByName(aFeld).AsString; except raise; end; end; end; finally MyQuery.Close; MyQuery.Free; end; end; Was mich übrigens noch interessieren würde ist: Zitat:
Gruß Michael |
AW: Fehlermeldung beim Zugriff auf die Datenbank
Zitat:
Hier das aktuellste Beispiel |
AW: Fehlermeldung beim Zugriff auf die Datenbank
Zitat:
|
AW: Fehlermeldung beim Zugriff auf die Datenbank
Zitat:
|
AW: Fehlermeldung beim Zugriff auf die Datenbank
Persönlich würd' ich diesen Teil umbauen:
Delphi-Quellcode:
In etwa so (das with lassen wir jetzt mal wie es ist, auch wenn ich es überhauptnicht mag ;-)):
if not (FieldByName(aFeld).IsNull) and
not (FieldByName(aFeld).asString.IsEmpty) and (Recordcount > 0) and ((FindField('GELOESCHT') = nil) or (Locate('GELOESCHT', 0, []))) then Result := FieldByName(aFeld).AsString;
Delphi-Quellcode:
Ist RecordCount = 0, muss nicht geprüft werden, ob es die Felder überhaupt gibt, spart die Suche der Felder und wenn die mal nil sein sollten, kracht es nicht, weil die erste Bedingung nicht erfüllt ist und damit die restlichen Prüfungen obsolet werden.
if (Recordcount > 0) and
not (FieldByName(aFeld).IsNull) and not (FieldByName(aFeld).asString.IsEmpty) and ((FindField('GELOESCHT') = nil) or (Locate('GELOESCHT', 0, []))) then Result := FieldByName(aFeld).AsString; Das ändert sich erst dann, wenn man in den Kompileroptionen das "Boolsche Asudrücke vollständig auswerten" aktiviert hat. Alternativ könntest Du vor
Delphi-Quellcode:
auch noch prüfen, ob
not (FieldByName(aFeld).IsNull)
Delphi-Quellcode:
, derweil: Das könnte (theoretisch) auch noch schief gehen.
and not (FindField(aFeld) = nil)
|
AW: Fehlermeldung beim Zugriff auf die Datenbank
Zitat:
P.S.: als Zeichen meiner Läuterung; hier der akutelle Code - ohne with - :roll:
Delphi-Quellcode:
function GetFeldwertFromID(aTabelle, aFeld: string; aID: integer): Variant;
var MyQuery: TFDQuery; begin Result := StrKeinEintrag; MyQuery := TFDQuery.Create(MyDB); try MyQuery.Connection := MyDB; if (MyQuery.Connection.Connected) and (aID > 0) then begin MyQuery.SQL.Text := 'select * from &pTabelle where ID = :pID'; MyQuery.MacroByName('pTabelle').asRaw := aTabelle; MyQuery.ParamByName('pId').asInteger := aId; try MyQuery.open; if (MyQuery.Recordcount > 0) and not (MyQuery.FieldByName(aFeld).IsNull) and not (MyQuery.FieldByName(aFeld).asString.IsEmpty) and ((MyQuery.FindField('GELOESCHT') = nil) or (MyQuery.Locate('GELOESCHT', 0, []))) then Result := MyQuery.FieldByName(aFeld).AsString; except raise; end; end; finally MyQuery.Close; MyQuery.Free; end; end; |
AW: Fehlermeldung beim Zugriff auf die Datenbank
Leider hat noch niemand wegen der ursprünglichen Fehlermeldung in Bezug auf die Datenbank etwas gepostet. Hat niemand eine Idee was das sein könnte - siehe Beitrag #1
VG Michael |
AW: Fehlermeldung beim Zugriff auf die Datenbank
Zitat:
Ältere Treiber (v10) funktionieren u.U. nicht. |
AW: Fehlermeldung beim Zugriff auf die Datenbank
Um den Fehler einzugrenzen, würde ich das SQL-Statement vor dem Open kopieren und prüfen, ob das grundsätzlich korrekt ist. Am Besten in einem passenden SQL-Editor ansehen und laufen lassen.
Wenn das funktioniert, vermute ich das Problem am Treiber (wie schon mehrfach vermutet wird) oder es gibt ein Initialisierungsproblem. Was mir gerade noch einfällt: Du weist die Connection in der Routine zu. Ist die Connection denn aktiv? Meistens werden Connections durch ein auszuführendes Query zwar implizit aktiv, aber erstens geht es hier um Access und zweitens um einen ODBC-Treiber. Es könnte also durchaus sein, dass die Connection noch gar nicht bereit, bzw. nicht schnell genug bereit ist. Das würde dann auch erklären, warum es nur beim ersten Durchlauf Probleme gibt. |
AW: Fehlermeldung beim Zugriff auf die Datenbank
Zitat:
|
AW: Fehlermeldung beim Zugriff auf die Datenbank
Hallo Forum,
erst mal danke für die Antworten. Zitat:
Code:
- so wirklich nichts spektakuläres.
Select * from Adresse where ID = 1.
Zitat:
Delphi-Quellcode:
Das scheidet als Fehlerursache meines Erachtens aus. Zumal die Fehlermeldung auch keine Exception auslöst, was bei einer nicht geöffneten Connection der Fall wäre.
MyQuery := TFDQuery.Create(MyDB);
try MyQuery.Connection := MyDB; if (MyQuery.Connection.Connected) and (aID > 0) then begin MyQuery.SQL.Text := 'select * from &pTabelle where ID = :pID'; MyQuery.MacroByName('pTabelle').asRaw := aTabelle; MyQuery.ParamByName('pId').asInteger := aId; try MyQuery.open; ..... except raise; end; VG Michael |
AW: Fehlermeldung beim Zugriff auf die Datenbank
Hallo Forum,
ich habe einen Case bei Embarcadero aufgemacht und von dort die Information erhalten, dass das gemeldete Problem bisher nicht bekannt ist. Außerdem würde FireDAC intern (es wird intern eine ODBC-Verbindung aufgebaut) ausschließlich den 'Microsoft.ACE.OLEDB.12.0' (Microsoft Access 2007) unterstützen??? Zitat:
Insofern könnte die Beschränkung von FireDAC auf die Verwendung des Microsoft Access 2007 Treiber ein massives Problem nach sich ziehen, da die Koexistenz einer Delphi Anwendung auf Basis von FD mit Microsoft Office 365 nicht mehr möglich wäre. Ich halte euch auf dem Laufenden ... VG Micheal |
AW: Fehlermeldung beim Zugriff auf die Datenbank
Hallo Michael,
deine Ausgangsfrage ging von Access 2012 und Firedac aus und das funktioniert bei mir mit Delphi 11. Access 365 ist eine andere Baustelle und hat bei mir Hausverbot. Gruß Alfred |
AW: Fehlermeldung beim Zugriff auf die Datenbank
Hallo Michael,
die Problemkreise 32Bit/64bit auf Seiten von Access geprüft? Problem "2 Accessversionen auf einem Rechner?" geprüft? Gruß Alfred |
AW: Fehlermeldung beim Zugriff auf die Datenbank
Erstellen Sie eine Sicherungskopie der ursprünglichen Datenbank. Versuchen Sie, diese Datenbank zu öffnen. Wenn Sie eine MDB-Datenbank im Access 97- oder Access 95-Dateiformat öffnen, zeigt Access das Dialogfeld Datenbankerweiterung an. Sie werden aufgefordert, die Datenbank zu aktualisieren.14-Feb-2022
.................................................. ............................... Fashion Mentions is one-stop destination for Latest Fashion Trends, Skin Care,insider beauty secrets, Makeup product reviews, and more |
AW: Fehlermeldung beim Zugriff auf die Datenbank
Zitat:
das ist auch so im Test. Der ursprünglich verwendete und getestete Treiber ist Access 2007. Aber ich habe halt die Erfahrung machen müssen, dass eine Office 365 Installation (egal ob auf eine Kundensystem oder auf einem Testsystem), den Access 2007 Treiber korrumpiert. Das Problem ist auch dann nur noch temporär über eine Reparaturinstallation des Access 2007 Treiber (Runtime) zu beheben. Aber leider kann ich meinen Kunden Office 365 nicht verbieten :wink: btw. das Problem hängt auch nicht nicht mit den Treibern zusammen, da es in jeder Konstellation auftritt. VG Michael |
AW: Fehlermeldung beim Zugriff auf die Datenbank
Zitat:
die Anwendung wird nur in 32-Bit für Access bereit gestellt - insofern wurde auch nur mit 32 Bit Anwendung und Treiber getestet. VG Michael |
AW: Fehlermeldung beim Zugriff auf die Datenbank
Zitat:
es ist schon eine Microsoft Access 2007 Datenbank. Die Datenbank hat eine Erweiterung .ACCDB und wird auch über die entsprechenden Treiber angesprochen. VG Michael |
AW: Fehlermeldung beim Zugriff auf die Datenbank
Hallo Forum,
heute habe ich eine Entdeckung gemacht, die mich der Lösung des Problem (zumindest an der derzeit betreffenden Stelle im Code) weiter gebracht hat: Ich habe festgestellt, dass die Fehlermeldung anscheinend mit der Verwendung von Views zusammenhängt. Ich hatte die betreffende Abfrage auf einen View bezogen, der Adressdaten aus einer Basistabelle aufbereitet. Wenn ich in der Abfrage den View (Adresse) gegen die Basistabelle (Adressen) austausche, wird keine Fehlermeldung mehr ausgegeben. Allerdings verlagert sich das Problem auf die nächste Abfrage, die auf einen View zugreift. Ich werde dieser Spur nachgehen und halte euch auf dem Laufenden. VG Michael P.S.: Ich habe zwischenzeitlich mit den Views in der Access Datenbank herumgespielt um herauszufinden, ob die Komplexität der SQL-Abfrage mit der Fehlermeldung in Verbindung steht. Dem ist nicht so, denn auch ein View mit eine sehr einfachen SQL-Abfrage löst das Problem aus.
Code:
select * from Adressen
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 00:11 Uhr. |
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