Entwickler-Ecke

Datenbanken - Abfrage aus Firebird Embedded DB gibt Fehler zurück


NOS1971 - Fr 20.03.15 18:20
Titel: Abfrage aus Firebird Embedded DB gibt Fehler zurück
Hallo zusammen,

ich habe in einer DB eine Liste von URLs mit verschiedenen Datensätzen ... ich lese nun einen Datensatz aus und zeige die Daten an ... dies Funktioniert bei einigen URL's aber nicht ... ich tippe mal darauf das es probleme mit dem ? oder & gibt aber ich bin mir nicht sicher ... habt ihr eine lösung dafür ?

Folgende URL's funktionieren nicht, obwohl das Adden zur DB damit funktionierte.

http://seoboxx.com/de/?format=feed&type=rss
http://seoboxx.com/de/?format=feed&type=atom
http://seoboxx.com/?format=feed&type=rss

Hier mal der Codeauszug:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
 CurrentConnection := TFDConnection.Create(nil);
 CurrentItem := TFDQuery.Create(nil);
 try
  CurrentConnection.LoginPrompt := false;
  CurrentConnection.UpdateOptions.LockWait := false;
  CurrentConnection.ConnectionName := 'seoBOXX-Database-ItemAccess';
  CurrentConnection.Params.DriverID := 'FB';
  CurrentConnection.Params.Database := DBFile;
  CurrentConnection.Params.Pooled := false;
  CurrentConnection.Params.UserName := sDBUserName;
  CurrentConnection.Params.Password := sDBPassword;
  CurrentConnection.Params.Add('OSAuthent=No');
  CurrentConnection.Params.Add('CharacterSet=utf8');
  CurrentConnection.Params.Add('Protocol=Local');
  CurrentConnection.Params.Add('DropDatabase=No');
  CurrentConnection.Params.Add('CreateDatabase=No');
  CurrentConnection.Params.Add('PageSize=16384');
  CurrentConnection.Params.Add('MonitorBy=Remote');
  CurrentConnection.Connected := true;
  // create database dataset and connect to database
  CurrentItem.Connection := CurrentConnection;
  // get url source
  CurrentURLSource := '';
  CurrentItem.Open('SELECT * FROM AnalyseResultURLSourceTable WHERE URL = ' + QuotedStr(URL) + ';');
  if not CurrentItem.IsEmpty then
  begin
   // item found
   CurrentItem.First;
   CurrentURLSource := CurrentItem.FieldByName('URLSOURCE').AsString;
  end;
  CurrentItem.Close;
  // get url dataset
  CurrentItem.Open('SELECT * FROM AnalyseResultURLTable WHERE URL = ' + QuotedStr(URL) + ';');
  if not CurrentItem.IsEmpty then
  begin
   // item found
   CurrentItem.First;


Delete - Fr 20.03.15 20:36

Zum Ersten: Die Fehlermeldung "funktioniert nicht" ist mir völlig unbekannt.

Zum Zweiten: Du arbeitest mit XE7, also Unicode-Strings. Welchen Zeichensatz hast du in deiner Firebird-Datenbank eingestellt? Ich würde hier UTF8 empfehlen.

Ich habe bislang noch keine Probleme mit Firebird-DB (UTF8) und Firedac von XE7 feststellen können. Wird alles korrekt in der DB gespeichert und auch wieder gelesen, auch Sondernzeichen, russische Zeichen, chinesische oder japanische, geht alles reibungslos.


NOS1971 - Fr 20.03.15 21:40

Hi Perlsau,

ok ... funktioniert nicht ist etwas global formuliert :-) ... mein Hauptproblem ist das ich keinen Fehler erhalte ... ich frage ja mit IsEmpty ab ob Datensätze vorhanden sind aber es sind keine vorhanden aber eine direkte Fehlermeldung gibt es nicht ... also im FDMonitor sehe ich auch nicht was das problem ist ... wenn ich in die DB schaue dann sehe ich aber die Einträge und die richtigen Daten (die URL) wird auch übergeben ...

die DB ist wie folgt initialisiert und auch mit UTF8 festgelegt


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
  con.Params.UserName := sDBUserName;
  con.Params.Password := sDBPassword;
  con.Params.Add('OSAuthent=No');
  con.Params.Add('CharacterSet=utf8');
  con.Params.Add('Protocol=Local');
  con.Params.Add('Database=' + FResultDatabaseFileName);
  con.Params.Add('PageSize=16384');
  con.Params.Add('MonitorBy=Remote');
  con.Params.Add('DropDatabase=No');
  con.Params.Add('CreateDatabase=Yes');


Delete - So 22.03.15 08:11

Was bewirkt denn dieser Parameter?


Delphi-Quelltext
1:
con.Params.Add('CreateDatabase=Yes');                    


NOS1971 - So 22.03.15 10:58

[quote="[delphi]con.Params.Add('CreateDatabase=Yes');[/delphi][/quote]

Das erzeugt das File für die DB ...


Delete - So 22.03.15 11:58

Bei jedem Programmstart?


NOS1971 - So 22.03.15 12:09

user profile iconPerlsau hat folgendes geschrieben Zum zitierten Posting springen:
Bei jedem Programmstart?


Nein ... das ist in einem Objekt bei jedem Start einer Analyse ... das Proggi ist ein Webseiten Spider / Analyser .... die DB wird erzeugt wenn du die Analyse startest ...

der Code für den Zugriff und das Auslesen:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
  CurrentConnection.Params.DriverID := 'FB';
  CurrentConnection.Params.Database := DBFile;
  CurrentConnection.Params.Pooled := false;
  CurrentConnection.Params.UserName := sDBUserName;
  CurrentConnection.Params.Password := sDBPassword;
  CurrentConnection.Params.Add('OSAuthent=No');
  CurrentConnection.Params.Add('CharacterSet=utf8');
  CurrentConnection.Params.Add('Protocol=Local');
  CurrentConnection.Params.Add('DropDatabase=No');
  CurrentConnection.Params.Add('CreateDatabase=No');
  CurrentConnection.Params.Add('PageSize=16384');
  CurrentConnection.Params.Add('MonitorBy=Remote');


Delete - So 22.03.15 18:20

Sorry, aber an diesem Code kann ich kein Auslesen erkennen ...


NOS1971 - So 22.03.15 18:42

Der Code für das Auslesen ist oben im ersten Posting .. es ging nur um das Init der DB Connection für das Auslesen was ich nochmal mitgeschickt habe um zu zeigen das es dort auch richtig gesetzt ist mit utf8 etc.


Delete - So 22.03.15 19:36

Bastel doch mal ein Beispielprojekt zusammen und stelle es hier ein, damit man das nachvollziehen kann. Im Moment kann ich nicht mehr dazu sagen, weil ich dein Projekt nicht kenne und daher auch nicht sehen kann, was wann & wo schiefläuft ...


NOS1971 - So 22.03.15 19:40

So ... kleines Demoprojekt ... reiner Ausleseversuch ... 4 URLs zur Auswahl ... mit der ersten gehts ... mit den anderen nicht .. denke mal du hast nen viewer um in die db zu schauen ob die anderen urls auch drin stehen


Delete - So 22.03.15 20:41

Weshalb hast du nicht gleich die ganze Button-Ereignisbehandlung hier reingestellt. Offenbar ist dir die Verwendung von Firedac mit einer Embedded-Firebird-DB noch nicht so geläufig. Wenn du wirklich die in deinem Programmverzeichnis befindliche Datenbank verwenden willst, dann mußt du das deinem Programm auch sagen, sonst wird nämlich alles über den installierten Firebird-Server abgewickelt und nicht über die fbembed.dll. Zudem solltest du keine relativen Dateipfade verwenden, denn dein Programm muß ja wissen, in welchem Verzeichnis die DB liegt. Zu guter Letzt sei noch angemerkt, daß Username und Passwort in Firebird nur 8 Zeichen aufnehmen können. Dein ellenlanges Passwort wird nach dem achten Zeichen automatisch abgeschnitten.

Dein Original-Code löste bei mir gleich den Fehler aus, daß Username und Passwort nicht definiert seien. Das heißt, in meiner Firebird-Server-Konfiguration gibt es diese Username-Passwort-Kombination nicht. Daran erkannte ich zweifelsfrei, daß dein Programm den Server verwendet und nicht die Embedded-DLL.

Ich hab hier mal ein paar Änderungen eingefügt, damit sollte es dann funktionieren:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
procedure TfrmMainForm.Button1Click(Sender: TObject);
var
 ProgrammPfad : String;
 CurrentConnection: TFDConnection;
 Phys : TFDPhysFBDriverLink;
 GuiCursor : TFDGUIxWaitCursor;
 CurrentItem: TFDQuery;
 URL: string;
begin
 ProgrammPfad := ExtractFilePath(ParamStr(0));
 URL := RadioGroup1.Items[RadioGroup1.ItemIndex];
 // create database connection
 GuiCursor := TFDGUIxWaitCursor.Create(nil);
 Phys := TFDPhysFBDriverLink.Create(nil);
 CurrentConnection := TFDConnection.Create(nil);
 CurrentItem := TFDQuery.Create(nil);
 try
  CurrentConnection.LoginPrompt := false;
  CurrentConnection.UpdateOptions.LockWait := false;
  CurrentConnection.ConnectionName := 'seoBOXX-Database-ItemAccess';
  CurrentConnection.Params.DriverID := 'FB';
  CurrentConnection.Params.Database := ProgrammPfad + 'SEOBOXX_21-03-2015_20-32-24.db';
  CurrentConnection.Params.Pooled := false;
  CurrentConnection.Params.UserName := sDBUserName;
  CurrentConnection.Params.Password := sDBPassword;
  CurrentConnection.Params.Add('OSAuthent=No');
  CurrentConnection.Params.Add('CharacterSet=utf8');
  CurrentConnection.Params.Add('Protocol=Local');
  CurrentConnection.Params.Add('DropDatabase=No');
  CurrentConnection.Params.Add('CreateDatabase=No');
  CurrentConnection.Params.Add('PageSize=16384');
  CurrentConnection.Params.Add('MonitorBy=Remote');

  Phys.VendorLib := ProgrammPfad + 'fbembed.dll';
  Phys.Embedded := True;

  CurrentConnection.Connected := true;
  // create database dataset and connect to database
  CurrentItem.Connection := CurrentConnection;
  // get url source
  CurrentItem.Open('SELECT * FROM AnalyseResultURLSourceTable WHERE URL = ' + QuotedStr(URL) + ';');
  if not CurrentItem.IsEmpty then
  begin
   // item found
   CurrentItem.First;
   ShowMessage(CurrentItem.FieldByName('URLSOURCE').AsString);
  end;
  CurrentItem.Close;
  CurrentItem.Open('SELECT * FROM AnalyseResultURLTable WHERE URL = ' + QuotedStr(URL) + ';');
  if not CurrentItem.IsEmpty then
  begin
   CurrentItem.First;
   ShowMessage(CurrentItem.FieldByName('MIMETYPE').AsString);
  end;
  CurrentItem.Close;
 finally
  CurrentItem.Connection := nil;
  CurrentItem.Free;
  CurrentConnection.Free;
 end;
end;


NOS1971 - So 22.03.15 20:49

So richtig geläufig ist mir die nicht ... es ist so das ich mir das alles mehr oder minder in den letzten monaten zusammengestrickt habe und es eigentlich bisher auf allen rechner so lief ... aber ich werde das gern im originalen source so ergänzen ... danke :-) ... in dem richtigen proggi sind die dateipfade zur db auch enthalten ... das er nicht die fbembedded.dll nimmt ist mir neu ... wußte nicht das ich das extra einstellen muss ... viel wichtiger ist allerdings das er die datensätze zu den links außer dem ersten nicht ausgibt ... und das ist eigentlich mein problem :-)


Lemmy - So 22.03.15 23:07

user profile iconNOS1971 hat folgendes geschrieben Zum zitierten Posting springen:
viel wichtiger ist allerdings das er die datensätze zu den links außer dem ersten nicht ausgibt ... und das ist eigentlich mein problem :-)


ganz einfach: Die kannst du nicht selektieren, weil die nicht in der DB stehen!

Das suchst du:

Quelltext
1:
seoboxx.com/de/?format=feed&type=rss                    


in der Datenbank steht aber anstelle des & zwischen feed und type=rss ein & amp; (Leerzeichen nur damit das Forum das nicht gleich wieder frisst... und das ist bei einem Textvergleich eben kein &

wird wohl bei den anderen genauso aussehen....


NOS1971 - Mo 23.03.15 09:50

Moin ...
ja ... genauso ist es ... das Forum frisst die & amp; .... habe ich auch gesehen ... drum habe ich das auch im code anders geadded und eine kurze routine geadded die die gesamten urls ausliest ... und wie zu sehen ist sind die auch dabei .... das auslesen einer einzelnen URL zum Testen erfolgt nun über Doppelclick auf den Eintrag im Listview ...

die URL's 2 und 3 (nur zwei der Beispiele) werden immer noch nicht ausgelesen und ich erhalte leider auch keinen Fehler ... bin etwas ratlos deswegen ... finde auch im FireDAC Monitor keinen Ansatz warum es nicht geht.


Lemmy - Fr 27.03.15 20:41

sorry, habe überlesen dass es damit auch nicht geht...

was erhälst Du denn bei den URL? keine einzige Message?

Leider habe ich Firedac nur bis XE5 und da gab es wohl einiges bis zur XE7, ich erhalte ständig einen Fehler bzgl. fehlender Berechtigungen, die Sourceunterschiede habe ich so weit angepasst.. -> sprich ich kann es nicht überprüfen.

Ich habe deine beiden Abfragen mit FlameRobin geprüft: es kommen Daten zurück


NOS1971 - Fr 27.03.15 20:46

Also wenn ich im FD Monitor schaue kommt nichts ... also ich sehe wirklich garnichts ... beim einlesen der datensätze sehe ich noch die anfragen an die db etc. ... nur bei den abfragen der urls sehe ich nichts mehr

ich kenne FlameRobin nicht ... checke ich aber mal und gebe dann nochmal laut :-)


Lemmy - Fr 27.03.15 21:13

http://flamerobin.org/
ist eine einfache KOnsolenanwendung.

Aber du kannst doch debuggen was beim Auslesen der problematischen URLs passiert. Sprich passt der SQL?....


NOS1971 - Fr 27.03.15 21:54



NOS1971 - Fr 27.03.15 21:56

Ich glaube ich sehe es selbst .... SQL scheint auch das & amp; zum & zu machen .... was kann man dagegen machen ?


NOS1971 - Fr 27.03.15 22:46

Es scheint am Prepare zu liegen .... kann man das ausschalten das der String verändert wird .... also das aus dem & amp; ein & wird


NOS1971 - Fr 10.04.15 13:43

Hat niemand einen Rat wie ich das mit dem Prepare in den Griff bekomme sodass aus & amp; im prepare kein & mehr gemacht wird ?


Sinspin - Sa 11.04.15 12:58

Hallo,

versuch es doch mal anders. Übergib den String als Parameter an die Query. Sehr wahrscheinlich wird er dann nicht verändert.

Delphi-Quelltext
1:
2:
3:
Query.SQL.Text := 'SELECT * FROM AnalyseResultURLSourceTable WHERE URL = :PURL';
Query.ParamByName('PURL').AsString := 'http://seoboxx.com/de/?format=feed&type=rss';
Query.Open;

Wobei... wenn ich mir den Log durchlese ist das noch nichtmal sicher das hier das Problem ist.
user profile iconLemmy hatte ja geschrieben das die Datensätze auch schon falsch in der DB stehen. & also durch &_amp; (ohne _) ersetzt ist.
Das die dann nicht gefunden werden ist kein Wunder.

Also schau Dir lieber mal an wie die Strings aussehen wenn sie in die Tabelle geschrieben werden. Würde mich nicht wundern wenn die mit amp; in den html texten stehen die Du zerflückst.


NOS1971 - Sa 11.04.15 13:05

Hi,

also es ist so ... die Daten stehen mit &_amp; in der DB weil die auch in dem html code so stehen .... ich würde die auch nur ungern verändern wollen weil es ja dem sourcecode entspricht .... ich probiere es mal mit der parameterübergabe und gebe dann laut :-)


NOS1971 - Sa 11.04.15 13:17

So ... eben gecheckt .... funzt nicht ... also in dem Demoproggi ist ja zu sehen das ich die Datensätze auslese und in den Listview adde ... also steht der DB Eintrag dort so wie er hier erscheint ... warum ist er nicht auslesbar ?????? Ich muss doch in einer DB speichern können was ich will und auslesen auch .... oder nicht ?


NOS1971 - Sa 02.05.15 11:27

Niemand eine Idee woran es liegen könnte ?