Zeos - ZUpdateSQL - Params.ParamByName geht nicht

Für Themen zu Datenbanken und Zugriff auf diese. Auch für Datenbankkomponenten.
Matze
Beiträge: 32
Registriert: Di 11. Jun 2013, 17:11

Zeos - ZUpdateSQL - Params.ParamByName geht nicht

Beitrag von Matze »

Hallo,

ich verstehe bei den Zeos Komponenten folgendes nicht, warum geht Beispiel 1 und in Beispiel 2 nur Delete und Modify? Einen Datensatz kann ich nicht einfügen.

Beispiel 1:

Code: Alles auswählen

begin
  Var1 := 'xyz';
  with DM.ZQuery do
  begin
    Active := False;
    SQL.Clear;
    SQL.Add('  SELECT                      ');
    SQL.Add('    T.Feld1,                  ');
    SQL.Add('    T.Feld2,                  ');
    SQL.Add('    T.Feld3,                  ');
    SQL.Add('    T.Feld4                   ');
    SQL.Add('  FROM                        ');
    SQL.Add('    tbl_tabelle T,            ');
    SQL.Add('  WHERE                       ');
    SQL.Add('    T.Feld3   LIKE :X         ');
    Params.ParamByName('X').Value := Var1;
    Active := True;
    Open;
  end;
end;  

Beispiel 2:

Code: Alles auswählen

begin
  Var1 := 'xyz';
  with DM.ZUpdateSQL do
  begin
 
    DeleteSQL.Add('  DELETE FROM tbl_tabelle                     ');
    DeleteSQL.Add('  WHERE       tbl_tabelle.Feld1 = :OLD_Feld1  ');       
 
    InsertSQL.Clear;
    InsertSQL.Add('  INSERT INTO tbl_tabelle   ');
    InsertSQL.Add('  (Feld1,                   ');
    InsertSQL.Add('  (Feld2,                   ');
    InsertSQL.Add('  (Feld3,                   ');
    InsertSQL.Add('   Feld4)                   ');
    InsertSQL.Add('  VALUES                    '); 
    InsertSQL.Add('  (:Feld1,                  '); 
    InsertSQL.Add('   :Feld2,                  '); 
    InsertSQL.Add('   :X,                      '); 
    InsertSQL.Add('   :Feld4)                  '); 
    Params.ParamByName('X').Value := Var1;
 
    ModifySQL.Clear;
    ModifySQL.Add('  UPDATE tbl_tabelle                          ');
    ModifySQL.Add('  Feld1  = :Feld1,                     ');
    ModifySQL.Add('  WHERE       tbl_tabelle.Feld1 = :OLD_Feld1  ');
 
  end;
end;
Ich benutze Lazarus 1.0.10 unter Windows 7, die Datenbank ist MySQL 5.5.32, DBEditfelder, DBNavigator und ZQuery mit ZUpdateSQL.

Die beiden Prozeduren führe ich gleich beim Programmstart aus. Wenn ich für Feld3 auch eine DBEdit Komponente verwende und den Wert per Hand einfüge funktioniert es. Es soll aber in Feld3 automatisch ein Wert aus der Variablen Var1 eingetragen werden. Aber mit dem Parameter geht das nicht. Es geht aber in Beispiel 1. Wo liegt denn da der Fehler?

Gruss Matze

hde
Beiträge: 556
Registriert: Mi 11. Aug 2010, 02:56

Re: Zeos - ZUpdateSQL - Params.ParamByName geht nicht

Beitrag von hde »

Bei einem Insert ist X kein Param sondern ein Value

NS.: wenn die die Statements einzeln genau ausführenwillst genügt ZQuery

hde

Matze
Beiträge: 32
Registriert: Di 11. Jun 2013, 17:11

Re: Zeos - ZUpdateSQL - Params.ParamByName geht nicht

Beitrag von Matze »

Bei einem Insert ist X kein Param sondern ein Value
OK, aber was muss ich denn darum nun anders machen?

NS.: wenn die die Statements einzeln genau ausführenwillst genügt ZQuery
Nein geht nicht, die ZQuery fragt mehrere Tabellen ab. Da muss ich die ZUpdateSQL benutzen. Aber in meinem Quelltext ist das so lang, darum habe ich mein Problem nur so kurz dargestellt.

hde
Beiträge: 556
Registriert: Mi 11. Aug 2010, 02:56

Re: Zeos - ZUpdateSQL - Params.ParamByName geht nicht

Beitrag von hde »

Doch, wenn die wie in deinem Beispiel eh jedesmal ein SQL.Clear machst und den Insert bzw. Update neu von dir formuliert einträgt dann reicht ein ZQuery.ExecSQL

Matze
Beiträge: 32
Registriert: Di 11. Jun 2013, 17:11

Re: Zeos - ZUpdateSQL - Params.ParamByName geht nicht

Beitrag von Matze »

Ich habe hier schon mal gefragt im Forum:
http://www.lazarusforum.de/viewtopic.php?f=17&t=7051
So bin ich erst auf die Zeos Komponenten gekommen und auf die Mglichkeit ZUpdateSQL einzusetzen. Ich dachte die sind Voraussetzung um Abfragen aus mehreren Tabellen zu updaten.
Jedenfall habe ich das Updateproblem damit lösen können. Wenn ich jetzt nur das ZQuery benutze geht doch das Update der Haupttabelle nicht mehr.

hde
Beiträge: 556
Registriert: Mi 11. Aug 2010, 02:56

Re: Zeos - ZUpdateSQL - Params.ParamByName geht nicht

Beitrag von hde »

Matze hat geschrieben:Ich dachte die sind Voraussetzung um Abfragen aus mehreren Tabellen zu updaten.
Jedenfall habe ich das Updateproblem damit lösen können. Wenn ich jetzt nur das ZQuery benutze geht doch das Update der Haupttabelle nicht mehr.
Wenn du in einem select mit joins das update automatiert willst, dann hast du Recht. In deinem Beispiel hast du insert, delete und update selbst formuliert, dann reicht ZQuery.

Matze
Beiträge: 32
Registriert: Di 11. Jun 2013, 17:11

Re: Zeos - ZUpdateSQL - Params.ParamByName geht nicht

Beitrag von Matze »

ok, ich habe das Beispiel noch mal anders geschrieben:

Code: Alles auswählen

begin
  Var1 := 'xyz';
  with DM.ZQuery do
  begin
    Active := False;
    SQL.Clear;                            
    SQL.Add('  SELECT                       ');
    SQL.Add('    T1.Feld1,                  ');
    SQL.Add('    T1.Feld2,                  ');
    SQL.Add('    T1.Feld3,                  ');
    SQL.Add('    T1.Feld4,                  ');
    SQL.Add('    T2.Feld1,                  ');
    SQL.Add('    T2.Feld2,                  ');
    SQL.Add('    T3.Feld1,                  ');
    SQL.Add('    T3.Feld2                   ');
    SQL.Add('  FROM                         ');
    SQL.Add('    tbl_tabelle1 T1,           ');
    SQL.Add('    tbl_tabelle2 T2,           ');
    SQL.Add('    tbl_tabelle3 T3            ');
    SQL.Add('  WHERE                        ');
    SQL.Add('    T1.Feld1 = T2.Feld1 AND    ');
    SQL.Add('    T1.Feld2 = T2.Feld2 AND    ');
    SQL.Add('    T1.Feld3   LIKE :X         ');
    Params.ParamByName('X').Value := Var1;
    Active := True;
    Open;
  end;
end;  
 
begin
  Var1 := 'xyz';
  with DM.ZUpdateSQL do
  begin
    DeleteSQL.Add('  DELETE FROM tbl_tabelle1                     ');
    DeleteSQL.Add('  WHERE       tbl_tabelle1.Feld1 = :OLD_Feld1  ');       
    InsertSQL.Clear;
    InsertSQL.Add('  INSERT INTO tbl_tabelle1                     ');
    InsertSQL.Add('  (Feld1,                                      ');
    InsertSQL.Add('   Feld2,                                      ');
    InsertSQL.Add('   Feld3,                                      ');
    InsertSQL.Add('   Feld4)                                      ');
    InsertSQL.Add('  VALUES                                       '); 
    InsertSQL.Add('  (:Feld1,                                     '); 
    InsertSQL.Add('   :Feld2,                                     '); 
    InsertSQL.Add('   :X,                                         '); 
    InsertSQL.Add('   :Feld4)                                     '); 
    Params.ParamByName('X').Value := Var1;
    ModifySQL.Clear;
    ModifySQL.Add('  UPDATE tbl_tabelle1                          ');
    ModifySQL.Add('  Feld1  = :Feld1,                             ');
    ModifySQL.Add('  Feld2  = :Feld2,                             ');
    ModifySQL.Add('  Feld4  = :Feld4,                             ');
    ModifySQL.Add('  WHERE  tbl_tabelle1.Feld1 = :OLD_Feld1       ');
  end;
end; 
Das ZQuery ist mit DBEdit Komponenten, dem DBNavigator und dem DBGrid verbunden. Was muss ich ändern, um dem X bei Insert einen Wert zuzuweisen?

hde
Beiträge: 556
Registriert: Mi 11. Aug 2010, 02:56

Re: Zeos - ZUpdateSQL - Params.ParamByName geht nicht

Beitrag von hde »

Ich verstehe deine ganze Konstruktion nicht wirklich. Du hast 3 Tabellen, aber nur eine ändert sich? Also sind die beiden anderen statisch. Das sieht für mich nach Lookup's aus, Warum nutzt du dann keine Lookups?

Und wenn schon ein Insert so formulieren willst, dann musst du den Wert von X im Statement auch wirklich zuweisen und nicht indirekt. Ist doch ein Value und kein Parameter

Matze
Beiträge: 32
Registriert: Di 11. Jun 2013, 17:11

Re: Zeos - ZUpdateSQL - Params.ParamByName geht nicht

Beitrag von Matze »

tbl_tabelle1 ist eine Detailtabelle (Child-Tabelle, abhängige Tabelle)
tbl_tabelle2 ist eine Primärtabelle (Parent-Tabelle)
tbl_tabelle3 ist eine Primärtabelle (Parent-Tabelle)
In der Detailtabelle stehen in einigen Feldern die Primärschlüssel von tbl_tabelle1 und 2 als Fremdschlüssel.
Ja, dazu benutze ich die DBLookupComboBoxen.
Im DBGrid sollen aber nicht die Primärschlüssel der Primärtabellen zu sehen sein, sondern die "richtigen" Bezeichnungen aus den anderen Feldern der Primärtabellen.
Darum die Abfrage aus allen drei Tabellen. Zum nur anzeigen (SELECT) ist die ZQuery ok.
Aber um ein Grid mit Daten aus mehreren Tabellen auch zu editieren (INSERT) muss man an die ZQuery eine ZUpdate Komponente hängen, auch wenn nur eine Tabelle geändert wird.
Soweit habe ich das mit Hilfe dieses Forum ja schon hinbekommen. Mit DBEditfeldern geht das einwanfrei. Aber wie kann ich ein Feld in der tbl_tabelle1 (Detailtabelle) mit einem Wert aus einer Variablen beim Neuanlegen eines Datensatzes füllen? Also ohne ein DBEdit Feld.

hde
Beiträge: 556
Registriert: Mi 11. Aug 2010, 02:56

Re: Zeos - ZUpdateSQL - Params.ParamByName geht nicht

Beitrag von hde »

Matze hat geschrieben:Aber um ein Grid mit Daten aus mehreren Tabellen auch zu editieren (INSERT) muss man an die ZQuery eine ZUpdate Komponente hängen, auch wenn nur eine Tabelle geändert wird.
Soweit habe ich das mit Hilfe dieses Forum ja schon hinbekommen.
Wenn du das automatisiert haben willst, z.B. per Navigator, dann hast du Recht.
Matze hat geschrieben:Aber wie kann ich ein Feld in der tbl_tabelle1 (Detailtabelle) mit einem Wert aus einer Variablen beim Neuanlegen eines Datensatzes füllen? Also ohne ein DBEdit Feld.
Gar nicht. Das ist nicht vorgesehen. Wenn das sein muss, dann musst du anders vorgehen, z.B. von Hand per ZQery.ExecSQL, o.dgl.
Aber, ich programmiere seit Delphi 1 auch in Pascal, darunter riesige Projekte, alle haben wir von vornherein so angelegt, dass ein solches Problem gar nicht erst auftrat.

Matze
Beiträge: 32
Registriert: Di 11. Jun 2013, 17:11

Re: Zeos - ZUpdateSQL - Params.ParamByName geht nicht

Beitrag von Matze »

Ach das ist ja doof, schade wenn das so nicht geht. Ich habe gedacht, ich kann beim INSERT Kommando in ein Feld der Detailtabelle (tbl_tabelle1) automatisch den aktuellen Primärschlüssel von tbl_tabelle3 (Eltern-Tabelle) eintragen. Nun muss ich an dieser Stelle noch mal ganz neu überlegen. Das ist nicht so leicht für mich. Im Gegensatz zu Dir programmiere ich mit Pascal nur, wenn ich mal eine DB für mich selbst benötige bzw. dadurch meinen Job interessanter machen kann. Das ist jetzt meine dritte DB seit Delphi 2 und sie fing so gut an.
Aber Danke für Deine Hilfe!

Gruss Matze

hde
Beiträge: 556
Registriert: Mi 11. Aug 2010, 02:56

Re: Zeos - ZUpdateSQL - Params.ParamByName geht nicht

Beitrag von hde »

Irgendwie versteh ich dein Problemnicht. Du nutzt doch LookupComboboxen, die tragen den Key doch richtig ins Datenfeld ein. Dann musst du das doch nicht so kompliziert machen?

mse
Beiträge: 2013
Registriert: Do 16. Okt 2008, 10:22
OS, Lazarus, FPC: Linux,Windows,FreeBSD,(MSEide+MSEgui 4.6,git master FPC 3.0.4,fixes_3_0)
CPU-Target: x86,x64,ARM

Re: Zeos - ZUpdateSQL - Params.ParamByName geht nicht

Beitrag von mse »

Matze hat geschrieben:

Code: Alles auswählen

 
[...]
    InsertSQL.Add('   :X,                                         '); 
    InsertSQL.Add('   :Feld4)                                     '); 
//    Params.ParamByName('X').Value := Var1; 
//den parameter-item X gibt es hier noch nicht, er wird erst beim
//parsen des statements angelegt. Also:
    params.createparam(ftstring,'X',ptunknown).value:= var1;
 
Ungeprüft!
MSEgui bietet für solche Fälle einiges. z.B. gibt es tfieldparamlink, tmseparam hat "connector", "datasource" und "fieldname" properties, tmsesqlquery hat "onbeforeapplyrecupdate" und "onapplyrecupdate" worin man in den Updateprozess eingreifen kann, die SQL statements erlauben die Verwendung von Macros usw.

Matze
Beiträge: 32
Registriert: Di 11. Jun 2013, 17:11

Re: Zeos - ZUpdateSQL - Params.ParamByName geht nicht

Beitrag von Matze »

Irgendwie versteh ich dein Problemnicht. Du nutzt doch LookupComboboxen, die tragen den Key doch richtig ins Datenfeld ein. Dann musst du das doch nicht so kompliziert machen?

In der Detailtabelle stehen meine Bestellungen. Zu jeder Bestellung gibt es mehrere Positionen. Diese stehen in der Primärtabelle. Eine Position lege ich immer für das aktuelle Projekt an. Ich kann das natürlich mit einer DBLookupCombobox machen, habe ich auch zum Testen gemacht, funktioniert. Ach eine DBEdit Komponente funktioniert. Aber das ist ja eine Fehlerquelle wenn ich ein falsches Projekt auswähle, denn das steht ja schon fest.

Ungeprüft!
MSEgui bietet für solche Fälle einiges. z.B. gibt es tfieldparamlink, tmseparam hat "connector", "datasource" und "fieldname" properties, tmsesqlquery hat "onbeforeapplyrecupdate" und "onapplyrecupdate" worin man in den Updateprozess eingreifen kann, die SQL statements erlauben die Verwendung von Macros usw.

Danke, Das werde ich mal versuchen.

EgonHugeist
Beiträge: 93
Registriert: Di 17. Apr 2012, 22:41

Re: Zeos - ZUpdateSQL - Params.ParamByName geht nicht

Beitrag von EgonHugeist »

@Matze

TZUpdateSQL parst nur die Parameter und läßt dir freie Wahl zum erstellen des Insert, Update, Delete und Refresh SQL's, um mit komplexen Queries zu Arbeiten. Außerdem kannst to mit der Compo die Parameter-Typen und Daten-Typen statisch einstellen.

TZUpdateSQL.Params[].As... macht gar keinen Sinn, da die TZQuery, welche mit TZUpdateSQL verlinkt ist, nun die Parameter erwartet. Soll heißen du mußt die Parameter and TZQuery.ParamByName('X') übergeben.

@Hans-Dieter

Danke für deinen immer währenden Support der Zeos User!
Es gilt hier noch zu sagen, das Zeos sehr wohl in der Lage ist, die Letzte ID zu determinieren, insofern Zeos darüber Bescheid weis(E.g. AutoInc-Fields). Jede DB hat ihre Eigenheiten. Für die meisten funzt das automatisch, bei DB's wie FireBird sollte man die Generatoren/Sequenzen Komponenten TZSequenze mit verknüpfen und die ID's werden automatisch mit generiert.

Zeos bietet auch eine extra Einstellung für Constraint-Rules wie Foreign-Keys und Master-Detail-Verknüfungen. Da alle DataSet-Descendants immer erst versuchen die Detail-DataSets abzudaten, maulen die meisten RDBM's wegen des fehlenden Master-Keys rum. TZDataSet.Options := [doUpdateMasterFirst] wirkt dem entgegen, schreibt zuerst die Master updates, determiert die ID's(sofern erkennbar) und stellt diese den Detail-Tabellen für deren Update-stmt zur Verfügung.

@MSE
Martin, habe mal ein Blick auf dein Project geworfen. Für mehr hat's mangels Zeit noch nicht gereicht. Daumen hoch und weiter so! Frage läuft Zeos auf dem MSEgui auch?

Edit: Zeos 7.0.6-stable ist gestern zum Download freigegeben wurden.
ZeosDevTeam

Antworten