Autor Beitrag
NOS1971
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 193

Windows 8.1 PRO 64 Bit
Delphi XE7 Professional
BeitragVerfasst: Sa 30.08.14 22:22 
Hallo zusammen,

ich möchte Multithreaded Einträge aus einer DB auslesen und bearbeiten und danach die Datensätze updaten. Damit die anderen Threads wissen ob ich den Datensatz grad bearbeite habe ich eine Statusfeld eingebaut

Ich hole mir am anfang mit einem FDQuery wie folgt den Datensatz:

ausblenden volle Höhe 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:
   
   // get current item from db
   try
    // do query next item to analyse
    conquery.Open('SELECT * FROM AnalyseResultURLTable WHERE STATUS = ' + QuotedStr('0') + ';');
    if not conquery.IsEmpty then
    begin
     // set variables
     FCurrentURL := '';
     FCurrentID := -1;
     // items found
     conquery.First;
     FCurrentURL := conquery.FieldByName('URL').AsString;
     FCurrentID := conquery.FieldByName('ID').AsInteger;
     conquery.Edit;
     conquery.FieldByName('STATUS').AsInteger := Integer(usPending);
     try
      conquery.Post;
     except
      on E : Exception do
      begin
       {$IFDEF DEBUG}
        OutputDebugString(PWideChar(E.Message + ' - [' + IntToStr(ThreadID) + '] - Status could not be updated - [' + IntToStr(FCurrentID) + ']' +  FCurrentURL));
       {$ENDIF}
      end;
     end;
     conquery.Close;
    end
    else
    begin
     // items not found
     {$IFDEF DEBUG}
      OutputDebugString(PWideChar(IntToStr(ThreadID) + ' - No Item found'));
     {$ENDIF}
     FCurrentURL := '';
     FCurrentID := -1;
     conquery.Close;
    end;
   except
    on E : Exception do
    {$IFDEF DEBUG}
     OutputDebugString(PWideChar(IntToStr(ThreadID) + ' - ' + E.Message));
    {$ENDIF}
   end;


Leider scheint der Datensatz nicht gelockt zu sein denn die anderen Threads können diesen ebenso noch auslesen. Was mache ich falsch ? Wie kann ich es machen das er nur einen Datensatz in der Table locked bzw. nur einen Datensatz in die Query liest ?

Grüße,
Andreas
Sinspin
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1321
Erhaltene Danke: 117

Win 10
RIO, CE, Lazarus
BeitragVerfasst: Mo 01.09.14 17:57 
Von was für einem Typ ist STATUS?
Ich vermute Integer. Warum prüfst du dann gegen einen String in deiner Query?
Ist "usPending" mit Sicherheit <> 0?
Arbeitest Du mit Transaktionen?

Wie meinst Du das überhaupt mit locken? Wenn man einen Datensatz in den EditMode setzt verhindert das ja nicht das er von anderen gelesen werden kann.
Erst wenn zwei Nutzer gleichzeitig versuchen den Datensatz in den EditMode zu setzen scheitert der zweite mit dem Versuch.

Willst Du STATUS als Flag dafür verwenden?

Erzähl mal mehr, ich werde irgenwie aus Deinem Quelltext snippet nicht ganz schlau ;-)

_________________
Wir zerstören die Natur und Wälder der Erde. Wir töten wilde Tiere für Trophäen. Wir produzieren Lebewesen als Massenware um sie nach wenigen Monaten zu töten. Warum sollte unser aller Mutter, die Natur, nicht die gleichen Rechte haben?

Für diesen Beitrag haben gedankt: NOS1971
NOS1971 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 193

Windows 8.1 PRO 64 Bit
Delphi XE7 Professional
BeitragVerfasst: Mo 01.09.14 18:49 
Hallo,

Status ist vom Typ Integer ... wie kann ich das denn in der Query nutzen ohne es in den String umzuwandeln ?
Soll ich es lieber so machen ? Richtig ... usPending ist = 1 und es ist auch richtig dass ich STATUS als flag nutzen will damit ich nur die Datensätze zur analyse nehme die noch nicht analysiert wurden .... ich bin allerdings ein ziemlicher DB neuling und bin nur bei datenbanken gelandet weil es bei großen datenmengen ein problem mit dem speicher gibt

das ganze proggi ist quasi ein webcrawler mit analysefunktionen ... das funktionierte mit einem TObjectDictionary auch multithreaded wirklich klasse aber nun mit datenbanken komme ich nicht weiter ... das problem ist einfach das ich auch shopseiten analysieren möchte und die liegen mit allen urls weit über 1 mio datensätzen ... transaktionen nutze ich nicht ...

ziel soll eigentlich sein das ein datensatz geholt wird ... der status auf 1 gesetzt wird damit er nicht nochmal analysiert wird ... die analyse laufen soll ... nach der analyse sollen die analysedaten in die db geschrieben werden, also der vorher geholte datensatz aktualisiert werden und der status auf 2 gesetzt werden ... während der analyse werden urls gefunden die dann unter ausschluss von duplikaten wieder in die db geadded werden .... ich hoffe das hilf zunächst als info ... im anhang noch ein kleines flussdiagram wie es grob im moment ist

wäre so der Querystring besser ?

ausblenden Delphi-Quelltext
1:
conquery.Open('SELECT * FROM AnalyseResultURLTable WHERE STATUS = "0";');					
Einloggen, um Attachments anzusehen!
Sinspin
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1321
Erhaltene Danke: 117

Win 10
RIO, CE, Lazarus
BeitragVerfasst: Mo 01.09.14 22:10 
So reicht das vollkommen aus:
ausblenden Delphi-Quelltext
1:
conquery.Open('SELECT * FROM AnalyseResultURLTable WHERE STATUS = 0;');					

Besser wäre es natürlich, nicht den Wert fest einzutragen sondern mit der für diesen Wert angelegten Konstante zu arbeiten :
ausblenden Delphi-Quelltext
1:
conquery.Open('SELECT * FROM AnalyseResultURLTable WHERE STATUS = ' + IntToStr(usOpen) + ';');					


Ich würde an der Stelle mit einem Master Thread arbeiten der die Arbeit für die Worker Threads generiert.

Die Query zur Abfrage aller verfügbaren Daten ist dann im Master und die Worker bekommen dann einen oder mehrere Datensätze zugeordnet die sie abarbeiten und den Status ändern wenn sie damit fertig sind. Ist der Master durch muss er warten bis alle Worker fertig sind. Dann kann er neu suchen.
Um die Datensätze einem Worker zuordnen zu können muss jeder Datensatz eine eindeutige Nummer haben. Ich verwende in jeder Tabelle für diesen Zweck ein Autoinc Feld von Typ Integer ("Id", zum Beispiel).
Da Du aber in den Workern neue Datensätze generierst, hat das ganze einen lustigen Effekt. Eine Query merkt sich bei ihrer Ausführung nicht alle Datensätze die die Bedingung erfüllen, sondern liefert einfach mit jedem Next einen der als nächstes in der Tabelle gefundenen Datensätze die zur Bedingung passen.
Erzeugt also ein Worker einen neuen Datensatz, findet der Master ihn mit dem nächsten Next und teilt ihn einem Worker zu.
Umgehen könnte man den Effekt indem der Master als erstes via UPDATE Statement alle passenden auf pending setzt. Also als erstes nix abruft, sondern conquery.Execute('UPDATE AnalyseResultURLTable SET STATUS = ' + IntToStr(usPending) + ' WHERE STATUS = ' + IntToStr(usOpen) + ';'); ausführt und sich dann via SELECT die Datensätze hohlt die pending sind.

Lege für das Autoinc Feld und für Status jeweils einen Index an, das beschleunigt die Suche bei Deinen zu erwartenden Datenmengen enorm.

_________________
Wir zerstören die Natur und Wälder der Erde. Wir töten wilde Tiere für Trophäen. Wir produzieren Lebewesen als Massenware um sie nach wenigen Monaten zu töten. Warum sollte unser aller Mutter, die Natur, nicht die gleichen Rechte haben?

Für diesen Beitrag haben gedankt: NOS1971
NOS1971 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 193

Windows 8.1 PRO 64 Bit
Delphi XE7 Professional
BeitragVerfasst: Mo 01.09.14 23:13 
Hallo,

ich werde das mal so versuchen einzubauen ... ist es denn nicht langsamer wenn der MasterThread immer wartet bis alle Threads zuende sind ? verstehe ich es recht das ich es jetzt auch schon so machen könnte das ich in jedem thread nur ein next aufrufe und nicht immer die query ausführen muss ? in meiner tabelle ist auf ein id feld welches ich automatisch inkrementiere ... einen index habe ich nur auf die url gelegt bisher ...

bevor ich das weiterbastele aber vorab eine frage die mich in der grundlage interessiert ... welche datenbank würdest du für dieses projekt nutzen ? im moment denke ich an firebird, weil es mir empfohlen wurde (embedded version) ... mit sqlite kenne ich mich ein wenig besser aus ... was ist die richtige wahl für mein vorhaben ?

Vielen Dank zunächst schon einmal für die Hilfe bis hierher :-)
Sinspin
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1321
Erhaltene Danke: 117

Win 10
RIO, CE, Lazarus
BeitragVerfasst: Di 02.09.14 17:07 
Ob der Master warten muss oder nicht, hängt mit der Implementierung zusammen. Wenn er einen Block erst als pending markiert und in dann vergibt muss er am Ende warten bis er wieder neue als pending markieren kann um sie dann zu vergeben. Denn es könnten ja noch welche von den Workern dabei sein die noch auf pending stehen weil die Worker es noch nicht geschafft haben sie abzuarbeiten.

Aber ich habe noch einen anderen Weg gefunden wo nicht gewartet werden muss.
Dabei kann es aber gut sein das Dein Master erst endet wenn keiner der Worker mehr neue Datensätze in die Tabelle einträgt. Was beim durchforsten des Internets ja doch schon etwas dauern kann ;-)
Bei der Methode sucht der Master nach allen offenen, setzt nacheinander die Datensätze auf pending (also der Master, nicht der Worker, das ist wichtig) und gibt die Datensätze dann an die Worker.

Ich hoffe mal, das Du eine gute Internetanbindung hast und einen Provider der nicht drosselt wenn ihm das ganz überhand nimmt.

Bezüglich der Datenbank.
Ich habe mich vor einiger Zeit mit Firebird befasst und war nicht wirklich angetan, da waren mir zu viele dämliche Einschränkungen. Wie Begrenzung der Länge von Feldnamen, Namen von Index müssen DB weit eindeutig sein. Verwendung von reservierten Wörtern als Feldnamen nicht wirklich möglich. Für mich ein unding für kommerzielle Projekte.
Ich hatte jetzt NexusDB in der Hand, voll Quelltext Engine, also keine Dll's, aber der Scriptumfang ist wirklich das letzte. Es ist nicht möglich alles an den Tabellen via SQL festzulegen, keine dynamischen Cursor, ... Habe keine kostenlose Version gefunden.
Privat arbeite ich mit Absolute Database, auch Quelltext Engine, also keine Dlls. Single File DB. Für privat kostenlos, aber mit der Einschrängkung das nur ein Nutzer eine DB offen haben darf. Wie gut die mit vielen Datensätzen umgehen kann, kann ich noch nicht sagen.
Nach wie vor finde ich Advantage Database (von Sybase/SAP) ganz in Ordnung. Muss installiert werden, man hat also Dll's. Bietet eine Engine für lokal liegende Datenbanken oder einen Server, der dann Geld kostet. Die DB kann gut mit großen Datenmengen umgehen. Ich verwende sie für kommerzielle Projekte.
Aktuell bereitet mir nur der Server etwas Kopfzerbrechen wenn Nutzer via WLAN arbeiten. Dann ist das öffnen von Tabellen die ein paar mehr Felder haben arbartig langsam.

_________________
Wir zerstören die Natur und Wälder der Erde. Wir töten wilde Tiere für Trophäen. Wir produzieren Lebewesen als Massenware um sie nach wenigen Monaten zu töten. Warum sollte unser aller Mutter, die Natur, nicht die gleichen Rechte haben?
NOS1971 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 193

Windows 8.1 PRO 64 Bit
Delphi XE7 Professional
BeitragVerfasst: Di 02.09.14 19:35 
Wie läuft die Kommunikation zwischen den Threads dann ab ? Via Threadmessage ? Ich habe oft gelesen das das massive Probleme bereiten kann und man darum auch die einzelnen Threads lieber die Arbeit holen lässt und auch die Datenbankzugriffe in jeden Thread einbaut ... wenn ich das richtig verstehe wäre Dein Ansatz das nur der MasterThread die Datensätze ausliest, den Status setzt und die Arbeit verteilt ... aber die Worker finden URLs und müssen diese in die DB eintragen und auch die Analyseergebnisse müssen am Ende eines Durchganges von dem Worker eingetragen werden ... somit ist doch alles in dem Worker drin bis auf das holen der Datensätze oder nicht ?

Ich habe es bisher so gemacht das das Ende dadurch erkannt wurde das die Anzahl der Analysierten = der Anzahl der Geaddeten war und die Anzahl der Aktiven Threads = 0 ... das funktionierte super

Bei der Datenbank ist es so das ich diesen Spider kostenlos ins Web stellen möchte aber schon so flexibel sein möchte daraus eventuell einmal eine Shareware oder kommerzielle Kleinlösung zu machen ... drum habe ich auch versucht SQLite und Firebird embedded zu nutzen ... das Hauptproblem bei all diesen Varianten der Datenbanken ist jedoch immer der schnelle Zugriff durch bis zu 200 Threads ... entweder verstehe ich das Pooling nicht oder es funktioniert nicht

Das Providerproblem und das sperren durch den Hoster habe ich schon durch ein automatisiertes Retry mit sich aufstockenden Wartezeiten und rotierenden UserAgents behoben :-) Das funktionierte bisher super.
Sinspin
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1321
Erhaltene Danke: 117

Win 10
RIO, CE, Lazarus
BeitragVerfasst: Mi 03.09.14 11:05 
user profile iconNOS1971 hat folgendes geschrieben Zum zitierten Posting springen:
Wie läuft die Kommunikation zwischen den Threads dann ab ? Via Threadmessage ? Ich habe oft gelesen das das massive Probleme bereiten kann und man darum auch die einzelnen Threads lieber die Arbeit holen lässt und auch die Datenbankzugriffe in jeden Thread einbaut ... wenn ich das richtig verstehe wäre Dein Ansatz das nur der MasterThread die Datensätze ausliest, den Status setzt und die Arbeit verteilt ... aber die Worker finden URLs und müssen diese in die DB eintragen und auch die Analyseergebnisse müssen am Ende eines Durchganges von dem Worker eingetragen werden ... somit ist doch alles in dem Worker drin bis auf das holen der Datensätze oder nicht ?

Jeder Thread braucht seine eigene Connection zum Zugriff auf die DB, wenn nicht bekommst Du eh Probleme beim schreiben in die DB.
Genau, das zuweisen der Arbeit darf eben nicht in den Workern erfolgen da sonst mehr als einer die gleichen Datensätze zur Verarbeitung hohlt.
Der Master erstellt die Worker. Somit kennt er die ja auch, und kann ihnen über eine Methode oder ein Property arbeit zuordnen und natürlich auch überwachen wann sie fertig sind. Besser, auf ein Ereignis warten das sie senden wenn sie neue arbeit brauchen.
Du kannst die Worker aber auch als einmal-Threads implementieren. Die beenden sich einfach wenn sie fertig sind und Du erstellt einen neuen für die nächste Aufgabe. Dann ist außer der Übergabe der zu verarbeitenden Datensätze (Id's) nix weiter nötig.

Mit Firebird solltest Du keine Probleme haben, auch bei vielen Threads. Wobei ich 200 zur gleichen Zeit schon ein bisschen viel finde. Das könnte schon alleine den Rechner etwas überfordern.

_________________
Wir zerstören die Natur und Wälder der Erde. Wir töten wilde Tiere für Trophäen. Wir produzieren Lebewesen als Massenware um sie nach wenigen Monaten zu töten. Warum sollte unser aller Mutter, die Natur, nicht die gleichen Rechte haben?

Für diesen Beitrag haben gedankt: NOS1971
NOS1971 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 193

Windows 8.1 PRO 64 Bit
Delphi XE7 Professional
BeitragVerfasst: Mi 03.09.14 17:10 
Hi Stefan,

ok ... soweit habe ich das gecheckt ... ich denke das ich in dem MasterThread in einer Schleife einfach abfragen kann ob ein Thread Idle ist (Flag im Thread) ... nun frage ich mich wie ich die daten in den workerthread bekomme .... oder nehme ich mir dazu 2 variablen im workerthread die ich dann vom masterthread aus befülle und dann ebenfalls ein flag im workerthread setze um die analyse zu beginnen...

wie findest du das ?

Hier mal ein aktueller FlowChart im Anhang
Einloggen, um Attachments anzusehen!
Sinspin
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1321
Erhaltene Danke: 117

Win 10
RIO, CE, Lazarus
BeitragVerfasst: Do 04.09.14 09:58 
Genau. Du könntest die Id eines Datensatzes über eine plublic Variable / Property an den WorkerThread übergeben und ihn dann mit einem Flag "anknipsen". Du brauchst eigentlich nur die Id des Datensatzes an den WorkerThread übergeben. Die anderen Daten kann er sich ja selber aus dem Datensatz hohlen. Er hat ja auch eine Query um dann seine eigenen Ergebnisse schreiben zu können.

Ich muss mal ganz vorsicht darauf hinweisen das ich ein leichtes Interesse an so einem Programm habe ;-). Werden nur die URL's verfolgt oder auch Inhalte, also Texte, Bilder, Medien runtergeladen?

Und nochwas, das Flussdiagram. Vorbildlich. Ich habe hier eine Hand voll Programme mit zusammen gut 500.000 Zeilen Quelltext, dafür gibt es Moduldokumentationen und Quelltextkommentare, mehr nicht. Weniger volbildlich aber es funktioniert auch.

_________________
Wir zerstören die Natur und Wälder der Erde. Wir töten wilde Tiere für Trophäen. Wir produzieren Lebewesen als Massenware um sie nach wenigen Monaten zu töten. Warum sollte unser aller Mutter, die Natur, nicht die gleichen Rechte haben?

Für diesen Beitrag haben gedankt: NOS1971
NOS1971 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 193

Windows 8.1 PRO 64 Bit
Delphi XE7 Professional
BeitragVerfasst: Do 04.09.14 11:16 
Moin Stefan,

ich denke ich übergebe dem Thread die URL und die ID ... so spare ich mir das holen des Datensatzes vor der Analyse ... das macht ja dann schon einiges aus bei der Menge an Datensätzen :-)
Du hast ein "leichtes Interesse" an meinem Proggi ... also prinzipiell ist das doch gut ;-) ... ich habe mir schon gedacht das es später in der GUI eine Abfrage gibt mit der man nach mime-type sortieren/abfragen oder anzeigen lassen kann und auch entsprechende files zum download markieren kann ... der crawler holt generell alle url's die möglich sind aus einer url ... also ich analysiere html,xml,css und ziehe daraus ebenfalls die url's somit bin ich auch von der anzahl der gefundenen url's weit vor anderen proggis soweit ich das verglichen habe

Das flowchart ist eher aus der not geboren ... ich dokumentiere auch meist nur im quelltext und in den modulen aber bei den vielen änderungen und varianten ist es auch mal sinnig dann ein flowchart zu erstellen :-) wer weiss wofür es noch gut ist :-)

Ich habe mal die aktuellste version des flowchart angehängt ... wenn sich da nichts mehr dran ändert werde ich mich wohl mal 2 tage einschliessen und das grundkonstrukt stricken ohne analyse etc.
Einloggen, um Attachments anzusehen!
ZeitGeist87
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 1593
Erhaltene Danke: 20

Win95-Win10
Delphi 10 Seattle, Rad Studio 2007, Delphi 7 Prof., C++, WSH, Turbo Pascal, PHP, Delphi X2
BeitragVerfasst: Do 04.09.14 11:41 
user profile iconSinspin hat folgendes geschrieben Zum zitierten Posting springen:
Besser wäre es natürlich, nicht den Wert fest einzutragen sondern mit der für diesen Wert angelegten Konstante zu arbeiten :
ausblenden Delphi-Quelltext
1:
conquery.Open('SELECT * FROM AnalyseResultURLTable WHERE STATUS = ' + IntToStr(usOpen) + ';');					



Und noch viel, viel besser wäre es, Parameter nicht auf diese Weise zu übergeben, sondern auf diese:

ausblenden Delphi-Quelltext
1:
2:
3:
conquery.SQL.Text:= 'SELECT * FROM AnalyseResultURLTable WHERE STATUS = :status';
conquery.ParamsByName('status').Value:= usOpen;
conquery.open;


Sorry, ich hab auf diese Art von Statements einen richtigen Hass entwickelt ;-)

Gruß,
Stefan

_________________
Wer Provokationen, Ironie, Sarkasmus oder Zynismus herauslesen kann soll sie ignorieren um den Inhalt meiner Beiträge ungetrübt erfassen zu können.

Für diesen Beitrag haben gedankt: NOS1971
Gerd Kayser
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 632
Erhaltene Danke: 121

Win 7 32-bit
Delphi 2006/XE
BeitragVerfasst: Do 04.09.14 13:14 
user profile iconNOS1971 hat folgendes geschrieben Zum zitierten Posting springen:
Wie kann ich es machen das er nur einen Datensatz [ ... ] in die Query liest ?

ausblenden SQL-Anweisung
1:
select * from ... where ... rows 1					

Für diesen Beitrag haben gedankt: NOS1971
Sinspin
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1321
Erhaltene Danke: 117

Win 10
RIO, CE, Lazarus
BeitragVerfasst: Do 04.09.14 17:43 
user profile iconZeitGeist87 hat folgendes geschrieben Zum zitierten Posting springen:
Und noch viel, viel besser wäre es, Parameter nicht auf diese Weise zu übergeben, sondern auf diese:

ausblenden Delphi-Quelltext
1:
2:
3:
conquery.SQL.Text:= 'SELECT * FROM AnalyseResultURLTable WHERE STATUS = :status';
conquery.ParamsByName('status').Value:= usOpen;
conquery.open;


Sorry, ich hab auf diese Art von Statements einen richtigen Hass entwickelt ;-)

Gruß,
Stefan

So? Hast Du das? Warum denn?
Bei Statements mit immer der gleichen Anzahl von Parametern mag das gehen. Aber ich generiere meine Statements meißt dynamisch. Die Anzahl der Parameter ist dann unterschiedlich. Da ist es einfach übersichtlicher wenn ich nur einmal aussortieren muss.

_________________
Wir zerstören die Natur und Wälder der Erde. Wir töten wilde Tiere für Trophäen. Wir produzieren Lebewesen als Massenware um sie nach wenigen Monaten zu töten. Warum sollte unser aller Mutter, die Natur, nicht die gleichen Rechte haben?

Für diesen Beitrag haben gedankt: NOS1971
ZeitGeist87
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 1593
Erhaltene Danke: 20

Win95-Win10
Delphi 10 Seattle, Rad Studio 2007, Delphi 7 Prof., C++, WSH, Turbo Pascal, PHP, Delphi X2
BeitragVerfasst: Do 04.09.14 21:30 
user profile iconSinspin hat folgendes geschrieben Zum zitierten Posting springen:
user profile iconZeitGeist87 hat folgendes geschrieben Zum zitierten Posting springen:
Und noch viel, viel besser wäre es, Parameter nicht auf diese Weise zu übergeben, sondern auf diese:

ausblenden Delphi-Quelltext
1:
2:
3:
conquery.SQL.Text:= 'SELECT * FROM AnalyseResultURLTable WHERE STATUS = :status';
conquery.ParamsByName('status').Value:= usOpen;
conquery.open;


Sorry, ich hab auf diese Art von Statements einen richtigen Hass entwickelt ;-)

Gruß,
Stefan

So? Hast Du das? Warum denn?
Bei Statements mit immer der gleichen Anzahl von Parametern mag das gehen. Aber ich generiere meine Statements meißt dynamisch. Die Anzahl der Parameter ist dann unterschiedlich. Da ist es einfach übersichtlicher wenn ich nur einmal aussortieren muss.


Ich mach das auch so mit dynamischen Statements.
Man muss es nur umsetzen können.

Es mag für deinen eigenen Fall nicht nötig sein, aber sobald das Statement im Code definiert und parametriert wird, ist es doch zwecks besserer Übersichtlichkeit sinnvoller, das so zu gestalten.

Du darfst es gern so machen. Meinen Azubis bringe ich das besser bei.

_________________
Wer Provokationen, Ironie, Sarkasmus oder Zynismus herauslesen kann soll sie ignorieren um den Inhalt meiner Beiträge ungetrübt erfassen zu können.
NOS1971 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 193

Windows 8.1 PRO 64 Bit
Delphi XE7 Professional
BeitragVerfasst: Sa 06.09.14 00:41 
So Stefan ... hier mal die letzte Version des FlowCharts ... ich beginne dann mal mit der Umsetzung :-)
Einloggen, um Attachments anzusehen!
NOS1971 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 193

Windows 8.1 PRO 64 Bit
Delphi XE7 Professional
BeitragVerfasst: So 07.09.14 01:28 
Ich baue das nun nach dem Flussdiagram langsam auf aber ich bekomme sobald ich in die DB schreiben will aus den workern nur "database is locked" fehler ....

bin da etwas ratlos im moment ...
Sinspin
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1321
Erhaltene Danke: 117

Win 10
RIO, CE, Lazarus
BeitragVerfasst: So 07.09.14 19:19 
Hey, falls Du es bisher noch nicht rausfinden konntest, kannst Du dazu bitte ein neues Thema anlegen? Ich kenne mich leider mit FireDac / Firebird auch nicht aus. Eine kurze Suche im Netz hat bisher auch nix zu Tage gefördert. Kann aber Morgen gerne nochmal schauen.

_________________
Wir zerstören die Natur und Wälder der Erde. Wir töten wilde Tiere für Trophäen. Wir produzieren Lebewesen als Massenware um sie nach wenigen Monaten zu töten. Warum sollte unser aller Mutter, die Natur, nicht die gleichen Rechte haben?

Für diesen Beitrag haben gedankt: NOS1971