MySQL Lösungen
- af0815
- Lazarusforum e. V.
- Beiträge: 6766
- Registriert: So 7. Jan 2007, 10:20
- OS, Lazarus, FPC: FPC fixes Lazarus fixes per fpcupdeluxe (win,linux,raspi)
- CPU-Target: 32Bit (64Bit)
- Wohnort: Burgenland
- Kontaktdaten:
Wieso ? Nagel mich jetzt nicht auf die 100% Richtigkeit fest, es geht um den Weg.
*) Statements für die Abfrage in SQL hinein ('select row1, row2, row3 from tablex where row1 = :param1' oder where weglassen und lokal filtern
*) Statement für das insert in InsertSQL hinein (insert tablex (row1, row2, row3) values (:param1, :param2, :param3)
falls du Updates/Deletes machst dann auch UpdateSQL und DeleteSQL
**) Die Parameter setzen
*) Die Datenmenge öffnen (lesend).
*) Jetzt kannst du schauen ob ein datensatz da ist
*) datenmenge auf insert setzen und den datensatz einfügen
*) Daten an DB schicken (ApplyUpdates)
*) Parameter/Filter ändern und bei ** weitermachen
Ich kenne die Anforderung zu wenig, aber vielleich kann man beim Insert gleich alles in einem rutsch erledigen.
Ich schau mir da gerne deinen Code an und optimiere das, wenn du willst. Ev. auch anhand eines neutralen Beispiels.
*) Statements für die Abfrage in SQL hinein ('select row1, row2, row3 from tablex where row1 = :param1' oder where weglassen und lokal filtern
*) Statement für das insert in InsertSQL hinein (insert tablex (row1, row2, row3) values (:param1, :param2, :param3)
falls du Updates/Deletes machst dann auch UpdateSQL und DeleteSQL
**) Die Parameter setzen
*) Die Datenmenge öffnen (lesend).
*) Jetzt kannst du schauen ob ein datensatz da ist
*) datenmenge auf insert setzen und den datensatz einfügen
*) Daten an DB schicken (ApplyUpdates)
*) Parameter/Filter ändern und bei ** weitermachen
Ich kenne die Anforderung zu wenig, aber vielleich kann man beim Insert gleich alles in einem rutsch erledigen.
Ich schau mir da gerne deinen Code an und optimiere das, wenn du willst. Ev. auch anhand eines neutralen Beispiels.
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).
- af0815
- Lazarusforum e. V.
- Beiträge: 6766
- Registriert: So 7. Jan 2007, 10:20
- OS, Lazarus, FPC: FPC fixes Lazarus fixes per fpcupdeluxe (win,linux,raspi)
- CPU-Target: 32Bit (64Bit)
- Wohnort: Burgenland
- Kontaktdaten:
Willst du jedesmal das SQL ändern, oder sauber mit Parametern arbeiten ?
Bezüglich Parameter, schau dir das Beispiel in Lazinfos (Stand svn 54 Seite 57 ) an. Dort wird ein SQL-Statement mit Parametern verwendet.
SCNR
Bezüglich Parameter, schau dir das Beispiel in Lazinfos (Stand svn 54 Seite 57 ) an. Dort wird ein SQL-Statement mit Parametern verwendet.
SCNR

Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).
- af0815
- Lazarusforum e. V.
- Beiträge: 6766
- Registriert: So 7. Jan 2007, 10:20
- OS, Lazarus, FPC: FPC fixes Lazarus fixes per fpcupdeluxe (win,linux,raspi)
- CPU-Target: 32Bit (64Bit)
- Wohnort: Burgenland
- Kontaktdaten:
Statt dem 'Wert' einfach ':Marke' verwenden und dann kannst du den Werte im Parameter 'Marke' eingeben.
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).
-
- Beiträge: 6079
- Registriert: Do 21. Sep 2006, 07:51
- OS, Lazarus, FPC: iWinux (L 1.x.xy FPC 2.y.z)
- CPU-Target: AVR,ARM,x86(-64)
- Wohnort: Dessau
- Kontaktdaten:
A sooo, den satz solltest noh in dein Buch eintrage. Der erzeugt sowas von nem AHA Effekt ...
Kann ich das auch so angeben das er sich das hinter dem : selbst bastelt ?
Über .FieldByName bekommt das Query ja den feldnamen z.b. schon übergeben. Könnte das Statement also komplett selbst basteln, geht das auch ?
Kann ich das auch so angeben das er sich das hinter dem : selbst bastelt ?
Über .FieldByName bekommt das Query ja den feldnamen z.b. schon übergeben. Könnte das Statement also komplett selbst basteln, geht das auch ?
W.m.k.A.h.e.m.F.h. -> http://www.gidf.de/
- af0815
- Lazarusforum e. V.
- Beiträge: 6766
- Registriert: So 7. Jan 2007, 10:20
- OS, Lazarus, FPC: FPC fixes Lazarus fixes per fpcupdeluxe (win,linux,raspi)
- CPU-Target: 32Bit (64Bit)
- Wohnort: Burgenland
- Kontaktdaten:
TSQLQuery bastelt sich sejhr viel selbst, wenn sie weß was du willst. Hast du besser beschreibendes Beispiel für mich ?
Übrigends werde ich es noch erklären, doch irgendwo musste ich ja bei LazInfos anfangen.
Übrigends werde ich es noch erklären, doch irgendwo musste ich ja bei LazInfos anfangen.
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).
-
- Beiträge: 6079
- Registriert: Do 21. Sep 2006, 07:51
- OS, Lazarus, FPC: iWinux (L 1.x.xy FPC 2.y.z)
- CPU-Target: AVR,ARM,x86(-64)
- Wohnort: Dessau
- Kontaktdaten:
Ich will einfach über FieldByName auf ein Feld zugreifen. Wie man das normalerweise bei anderen DataSets auch macht, im Falle Query kann sich das Query aus
Query1.FieldByName('MEINFELD').AsString := 'test';
ein
insert 'tablename'('MEINFELD') values ('test');
basteln.
dazu könnte z.b. im InsertSQL
insert 'tablename'(':%FIELDNAME%') values ('%FIELDVALUE%');
stehen o.ä. ich bin der meinung das ich mal sowas gelesen hab, aber ...
Query1.FieldByName('MEINFELD').AsString := 'test';
ein
insert 'tablename'('MEINFELD') values ('test');
basteln.
dazu könnte z.b. im InsertSQL
insert 'tablename'(':%FIELDNAME%') values ('%FIELDVALUE%');
stehen o.ä. ich bin der meinung das ich mal sowas gelesen hab, aber ...
W.m.k.A.h.e.m.F.h. -> http://www.gidf.de/
-
- Lazarusforum e. V.
- Beiträge: 2809
- Registriert: Sa 9. Sep 2006, 18:05
- OS, Lazarus, FPC: Linux (L trunk FPC trunk)
- CPU-Target: 64Bit
- Wohnort: Dresden
- Kontaktdaten:
Versteh ich jetzt nicht ganz...willst du wissen, wie du auf die Parameter zugreifen kannst? Da war oben inm meinem Code nen Beispiel. Über Params.ParamByName('name ohne :').AsString
Soweit ich das seh, was du eigentlich machen willst, kommt mir der Gedanke, das der Lösungsweg doch nicht ganz optimal ist.
Gerade da du dich ja über die komplizierten Abfragen beschwerst, wenn du erstmal ermitteln musst, ob der DS exitiert.
Müsstest es zwar in jedem Datenbanksystem neu machen, aber überleg dir auch mal, ob du es nicht mit Stored Procedures serverseitig mahen willst.
Belastet auf alle fälle weniger das Frontend und das Netzwerk (je nach Einsatz).
Somit sollte das ganze so ablaufen:
>>Deine Anwednung schickt den Datensatz an den Server, einmalig mit EXECUTE ProcedureXY
alles andere macht der Server mit der Richtigen Procedure (die du natürlich schreiben musst) aber so kannst du alles gleich dort erledigen:
- Kontrolle, ob ie Daten gültig sind
- bei Bedarf neu anlegen
- Herstellen der referenziellen Integrität
- wenn es schon existiert, aktualisieren
Und du musst die daten nur einmal senden, der DB-Server bastelt sie sich dann zurecht. Auf DB-Seite musst du lediglich einmalig die entsprechende StoredProcedure erstellen.
Soweit ich das seh, was du eigentlich machen willst, kommt mir der Gedanke, das der Lösungsweg doch nicht ganz optimal ist.
Gerade da du dich ja über die komplizierten Abfragen beschwerst, wenn du erstmal ermitteln musst, ob der DS exitiert.
Müsstest es zwar in jedem Datenbanksystem neu machen, aber überleg dir auch mal, ob du es nicht mit Stored Procedures serverseitig mahen willst.
Belastet auf alle fälle weniger das Frontend und das Netzwerk (je nach Einsatz).
Somit sollte das ganze so ablaufen:
>>Deine Anwednung schickt den Datensatz an den Server, einmalig mit EXECUTE ProcedureXY
alles andere macht der Server mit der Richtigen Procedure (die du natürlich schreiben musst) aber so kannst du alles gleich dort erledigen:
- Kontrolle, ob ie Daten gültig sind
- bei Bedarf neu anlegen
- Herstellen der referenziellen Integrität
- wenn es schon existiert, aktualisieren
Und du musst die daten nur einmal senden, der DB-Server bastelt sie sich dann zurecht. Auf DB-Seite musst du lediglich einmalig die entsprechende StoredProcedure erstellen.
Johannes
-
- Beiträge: 6079
- Registriert: Do 21. Sep 2006, 07:51
- OS, Lazarus, FPC: iWinux (L 1.x.xy FPC 2.y.z)
- CPU-Target: AVR,ARM,x86(-64)
- Wohnort: Dessau
- Kontaktdaten:
Die wäre auch riesig, da es schon mal sein kann das ich 10000 Datensätze mit einem mal einfügen will aber das wäre noch n ansatz. Kann man die denn DBS übergreifend schreiben ? Oder stürz ich mich dann wieder in Abhängigkeiten ansonsten kann ich auch einfach if exists anhängen das kennt vieleicht nicht jedes DBS aber mysql kennts...
W.m.k.A.h.e.m.F.h. -> http://www.gidf.de/
-
- Lazarusforum e. V.
- Beiträge: 2809
- Registriert: Sa 9. Sep 2006, 18:05
- OS, Lazarus, FPC: Linux (L trunk FPC trunk)
- CPU-Target: 64Bit
- Wohnort: Dresden
- Kontaktdaten:
Die wäre nicht riesig. Wenn du 10000Datensätze einfügst, wird die ja auch 10000mal aufgerufen. Davon wird die Procedure aber nicht gößer 
Kommt darauf an, wie du sie Programmierst, und welche speziallbefehle du verwendest. Wenn du bei den Grundlegenden bleibst, sollte sie sich relativ leicht übertragen lassen. Kann natürlich nicht ausgeschlossen werden, das ne Anpassung nötig ist. Aber auf der anderen Seite, wenn deine Anwednung Befehle nutzt, die bspw. Firebird nicht kennt, musst du genau so anpassen, wie so eben die SP.
Und IF EXISTS sollte eigentlich ne vernünftige DB kennen.
Ich finde die Variante auf jeden Fall zu bevorzugen, wenn du viele Tabellen hast. Verknüpfe mal 20, 30 Tabellen mit Frontendlogig so, dass eine schön normalisierte DB entsteht, da spart man locker 95% der Abfragen ein.

Kommt darauf an, wie du sie Programmierst, und welche speziallbefehle du verwendest. Wenn du bei den Grundlegenden bleibst, sollte sie sich relativ leicht übertragen lassen. Kann natürlich nicht ausgeschlossen werden, das ne Anpassung nötig ist. Aber auf der anderen Seite, wenn deine Anwednung Befehle nutzt, die bspw. Firebird nicht kennt, musst du genau so anpassen, wie so eben die SP.
Und IF EXISTS sollte eigentlich ne vernünftige DB kennen.
Ich finde die Variante auf jeden Fall zu bevorzugen, wenn du viele Tabellen hast. Verknüpfe mal 20, 30 Tabellen mit Frontendlogig so, dass eine schön normalisierte DB entsteht, da spart man locker 95% der Abfragen ein.
Johannes
-
- Lazarusforum e. V.
- Beiträge: 2809
- Registriert: Sa 9. Sep 2006, 18:05
- OS, Lazarus, FPC: Linux (L trunk FPC trunk)
- CPU-Target: 64Bit
- Wohnort: Dresden
- Kontaktdaten:
Nein...ich such dir mal nen kleines, reales Beispiel raus...als Beispiel nehm ich mal was einfaches:
- ne Zitatdatenbank mit zwei Tabellen, eine Tabelle enthält die Verfasser, die andere die entsprechenden Zitate.
Die Serverseitige SP verknüpft dabei selbstständig die Zitate mit dem richtigen Eintrag bei den Autoren über einen Schlüssel. Ich denk, die Felder sollten bei dieser abgespeckten Darstellung selbsterklärend sein.
Hier die SP (Ausschnitt aus der DDL zum erstellen):
XVerfasser und XZitat sind Eingabeparameter, welche von deinem Frontend übergeben werden müssen. Die Variable ID wird nur intern gehandhabt und kann dem Frontend egal sein.
Für jedes Zitat, was eingefügt wird, ist im Frontend lediglich folgender Aufruf nötig:
In der Eigenschaft SQL werden die Eingabeparameter also mit ':' begonnen, was der Query verdeutlicht, das es sich um Parameter handelt, um darauf zuzugreifen über Params.ParamByName nutzt man allerdings nur den namen ohne ':'.
Und für viele Datensätze brauchst du nur obigen Pascalcode von 4 relevanten Zeilen in ne Schleife verpacken und fertig. Dann wird automatisch für jeden neuen Datesatz die SP ausgeführt.
Und was nun genau in der SP steht, kann natürlich auch wesentlich umfangreicher sein. Und ich hatte mit SQLdb StoredProcs mit mehreren dutzend Parametern und es ging ohne Probleme.
- ne Zitatdatenbank mit zwei Tabellen, eine Tabelle enthält die Verfasser, die andere die entsprechenden Zitate.
Die Serverseitige SP verknüpft dabei selbstständig die Zitate mit dem richtigen Eintrag bei den Autoren über einen Schlüssel. Ich denk, die Felder sollten bei dieser abgespeckten Darstellung selbsterklärend sein.
Hier die SP (Ausschnitt aus der DDL zum erstellen):
Code: Alles auswählen
CREATE PROCEDURE ADD_ZITAT (
XVERFASSER varchar(100),
XZITAT varchar(10000))
AS
declare variable ID smallint;
begin
//ab hier kommt der Code, der für jeden Aufruf der SP ausgeführt wird
IF (NOT EXISTS (SELECT id FROM verfasser
WHERE verfasser.verfasser = :XVERFASSER))
then
begin
INSERT INTO verfasser
(Verfasser)
VALUES
(:XVERFASSER);
INSERT INTO zitate
(Zitat, id_verfasser)
VALUES
(:XZITAT, gen_id(gen_verfasser_id, 0));
end
else
begin
SELECT Id FROM verfasser
WHERE verfasser = :XVERFASSER
INTO :ID;
INSERT INTO zitate
(id_Verfasser, zitat)
VALUES
(:ID, :XZITAT);
end
suspend;
end
Für jedes Zitat, was eingefügt wird, ist im Frontend lediglich folgender Aufruf nötig:
Code: Alles auswählen
with Query do
begin
SQL.Text := 'EXECUTE PROCEDURE Add_Zitat (:XVerfasser, :XZitat)';
Params.ParamByName('XVerfasser').AsString := Param_Autor;
Params.ParamByName('XZitat').AsString := Param_Text;
ExecSQL;
end;
//als Abschluss natürlich irgendwann ein Commit
Und für viele Datensätze brauchst du nur obigen Pascalcode von 4 relevanten Zeilen in ne Schleife verpacken und fertig. Dann wird automatisch für jeden neuen Datesatz die SP ausgeführt.
Und was nun genau in der SP steht, kann natürlich auch wesentlich umfangreicher sein. Und ich hatte mit SQLdb StoredProcs mit mehreren dutzend Parametern und es ging ohne Probleme.
Zuletzt geändert von monta am Mi 31. Okt 2007, 17:19, insgesamt 1-mal geändert.
Johannes