MySQL Lösungen

Für Themen zu Datenbanken und Zugriff auf diese. Auch für Datenbankkomponenten.
Benutzeravatar
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:

Beitrag von af0815 »

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.
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).

Christian
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:

Beitrag von Christian »

Parameter setzen ???
W.m.k.A.h.e.m.F.h. -> http://www.gidf.de/

Benutzeravatar
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:

Beitrag von af0815 »

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 :-)
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).

Christian
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:

Beitrag von Christian »

Momentan ändere ich das SQL das mit den Parametern ist mir noch zu undurchsichtig. In den lazInfos hast du zwar Beispiele aber aus den 2 Beispielen ersehe ich nicht wie man mit den Dingern umgeht.
W.m.k.A.h.e.m.F.h. -> http://www.gidf.de/

Benutzeravatar
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:

Beitrag von af0815 »

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).

Christian
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:

Beitrag von Christian »

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 ?
W.m.k.A.h.e.m.F.h. -> http://www.gidf.de/

Benutzeravatar
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:

Beitrag von af0815 »

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.
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).

Christian
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:

Beitrag von Christian »

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 ...
W.m.k.A.h.e.m.F.h. -> http://www.gidf.de/

monta
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:

Beitrag von monta »

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.
Johannes

Christian
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:

Beitrag von Christian »

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/

monta
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:

Beitrag von monta »

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.
Johannes

Christian
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:

Beitrag von Christian »

Ich muss doch dann die Daten die ich inserten will auch in die Stored proc mit reinbasteln oder ?
W.m.k.A.h.e.m.F.h. -> http://www.gidf.de/

monta
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:

Beitrag von monta »

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):

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
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:

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
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.
Zuletzt geändert von monta am Mi 31. Okt 2007, 17:19, insgesamt 1-mal geändert.
Johannes

Christian
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:

Beitrag von Christian »

Super
W.m.k.A.h.e.m.F.h. -> http://www.gidf.de/

monta
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:

Beitrag von monta »

siehe oben, hoffe, das verdeutlicht es etwas...hab was hoffentlich selbsterklärendes gesucht...was ich aber auch wirklich laufen hab mit SQLdb.
Johannes

Antworten