Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Datenbanken (https://www.delphipraxis.net/15-datenbanken/)
-   -   MySQL Query Update funktioniert nicht (https://www.delphipraxis.net/187114-mysql-query-update-funktioniert-nicht.html)

akio87 28. Okt 2015 17:27

Datenbank: MySQL • Version: 5 • Zugriff über: ??

MySQL Query Update funktioniert nicht
 
Hallo,

ich habe festgestellt, dass meine alte Update Funktion, siehe 2. Code, in der BDGrid mit einem Leerem String nicht funktioniert. In der neuen Variante, wo ich dachte, das es dort geht, funktioniert der leere String ebenfalls nicht + Update generell nicht, mit folgender Fehlermeldung:
Error: SQL Syntax...

Habt ihr eine Idee?

NEU:
Code:
  MainModule.UniMainModule.mySQLUpdateSQL1.ModifySQL.Clear;
  MainModule.UniMainModule.mySQLUpdateSQL1.ModifySQL.Add('update `' + Tabelle + '`');
  MainModule.UniMainModule.mySQLUpdateSQL1.ModifySQL.Add('set ');
  MainModule.UniMainModule.mySQLUpdateSQL1.ModifySQL.Add('Firma = :Firma, ');
  MainModule.UniMainModule.mySQLUpdateSQL1.ModifySQL.Add('Adress1 = :Adress1, ');
  MainModule.UniMainModule.mySQLUpdateSQL1.ModifySQL.Add('Adress2 = :Adress2, ');
  MainModule.UniMainModule.mySQLUpdateSQL1.ModifySQL.Add('Straße = :Straße, ');
  MainModule.UniMainModule.mySQLUpdateSQL1.ModifySQL.Add('PLZ = :PLZ, ');
  MainModule.UniMainModule.mySQLUpdateSQL1.ModifySQL.Add('Ort = :Ort, ');
  MainModule.UniMainModule.mySQLUpdateSQL1.ModifySQL.Add('Land = :Land, ');
  MainModule.UniMainModule.mySQLUpdateSQL1.ModifySQL.Add('Such1 = :Such1 ');
  MainModule.UniMainModule.mySQLUpdateSQL1.ModifySQL.Add('Such2 = :Such2 ');
  MainModule.UniMainModule.mySQLUpdateSQL1.ModifySQL.Add('where ');
  MainModule.UniMainModule.mySQLUpdateSQL1.ModifySQL.Add('Firma = :OLD_Firma and ');
  MainModule.UniMainModule.mySQLUpdateSQL1.ModifySQL.Add('Adress1 = :OLD_Adress1 and ');
  MainModule.UniMainModule.mySQLUpdateSQL1.ModifySQL.Add('Adress2 = :OLD_Adress2 and ');
  MainModule.UniMainModule.mySQLUpdateSQL1.ModifySQL.Add('Straße = :OLD_Straße and ');
  MainModule.UniMainModule.mySQLUpdateSQL1.ModifySQL.Add('PLZ = :OLD_PLZ and ');
  MainModule.UniMainModule.mySQLUpdateSQL1.ModifySQL.Add('Ort = :OLD_Ort and ');
  MainModule.UniMainModule.mySQLUpdateSQL1.ModifySQL.Add('Land = :OLD_Land and ');
  MainModule.UniMainModule.mySQLUpdateSQL1.ModifySQL.Add('Such1 = :OLD_Such1 and ');
  MainModule.UniMainModule.mySQLUpdateSQL1.ModifySQL.Add('Such2 = :OLD_Such2;');

Mein Alter Code: Da ging die Update Funktion. Bis auf einem Leeren String....
Code:
{MainModule.UniMainModule.mySQLUpdateSQL1.ModifySQL.Text := 'update ' + Tabelle + #10 +
                                                            'set' + #10 +
                                                            ' Firma = :Firma,'+ #10 +
                                                            ' Adress1 = :Adress1,'+ #10 +
                                                            ' Adress2 = :Adress2,'+ #10 +
                                                            ' Straße = :Straße,'+ #10 +
                                                            ' PLZ = :PLZ,'+ #10 +
                                                            ' Ort = :Ort,'+ #10 +
                                                            ' Land = :Land,'+ #10 +
                                                            ' Such1 = :Such1,'+ #10 +
                                                            ' Such2 = :Such2'+ #10 +
                                                            'where'+ #10 +
                                                            ' Firma = :OLD_Firma and'+ #10 +
                                                            ' Adress1 = :OLD_Adress1 and'+ #10 +
                                                            ' Adress2 = :OLD_Adress2 and'+ #10 +
                                                            ' Straße = :OLD_Straße and'+ #10 +
                                                            ' PLZ = :OLD_PLZ and'+ #10 +
                                                            ' Ort = :OLD_Ort and'+ #10 +
                                                            ' Land = :OLD_Land and'+ #10 +
                                                            ' Such1 = :OLD_Such1 and'+ #10 +
                                                            ' Such2 = :OLD_Such2';
 }

nahpets 28. Okt 2015 17:39

AW: MySQL Query Update funktioniert nicht
 
fehlt da ein Komma?
Delphi-Quellcode:
  MainModule.UniMainModule.mySQLUpdateSQL1.ModifySQL.Add('Such1 = :Such1 ');
Wie befüllst Du denn die Parameter? (Quellcode dazu?)

Was meinst Du mit 'leere String'?

Wo ist der im geposteten Quelltext zu suchen?

akio87 28. Okt 2015 17:48

AW: MySQL Query Update funktioniert nicht
 
Hallo,

mein Gott hast Du scharfsinnige Augen :D

Das Updaten der Zeilen funktioniert jetzt, Danke deiner Hilfe.

Leider noch keine Leeren Datensätze, also "" Zellen... Mal Angenommen, ich möchte das Adressfeld1 leeren und speichern in der DBGrid. Das wird nicht übernommen.

DBGrid.Datasource -> UniMainModule.DataSource3.Dataset -> mySQLQuery3.UpdateObject -> mySQLUpdateSQL1

Code komplett:
Code:
procedure TfmAdressverwaltung.UniFormShow(Sender: TObject);
begin
  UniButton1.Click;
end;

procedure TfmAdressverwaltung.UniButton1Click(Sender: TObject);
var
  search, Tabelle: String;
begin

  if UniMainModule.RRSuche = True then
   begin
     Tabelle := 'Rechnungsadressen';
   end else
   begin
     Tabelle := 'Lieferadressen';
   end;

  MainModule.UniMainModule.mySQLUpdateSQL1.ModifySQL.Clear;
  MainModule.UniMainModule.mySQLUpdateSQL1.ModifySQL.Add('update `' + Tabelle + '`');
  MainModule.UniMainModule.mySQLUpdateSQL1.ModifySQL.Add('set');
  MainModule.UniMainModule.mySQLUpdateSQL1.ModifySQL.Add('Firma = :Firma,');
  MainModule.UniMainModule.mySQLUpdateSQL1.ModifySQL.Add('Adress1 = :Adress1,');
  MainModule.UniMainModule.mySQLUpdateSQL1.ModifySQL.Add('Adress2 = :Adress2,');
  MainModule.UniMainModule.mySQLUpdateSQL1.ModifySQL.Add('Straße = :Straße,');
  MainModule.UniMainModule.mySQLUpdateSQL1.ModifySQL.Add('PLZ = :PLZ,');
  MainModule.UniMainModule.mySQLUpdateSQL1.ModifySQL.Add('Ort = :Ort,');
  MainModule.UniMainModule.mySQLUpdateSQL1.ModifySQL.Add('Land = :Land,');
  MainModule.UniMainModule.mySQLUpdateSQL1.ModifySQL.Add('Such1 = :Such1,');
  MainModule.UniMainModule.mySQLUpdateSQL1.ModifySQL.Add('Such2 = :Such2');
  MainModule.UniMainModule.mySQLUpdateSQL1.ModifySQL.Add('where');
  MainModule.UniMainModule.mySQLUpdateSQL1.ModifySQL.Add('Firma = :OLD_Firma and');
  MainModule.UniMainModule.mySQLUpdateSQL1.ModifySQL.Add('Adress1 = :OLD_Adress1 and');
  MainModule.UniMainModule.mySQLUpdateSQL1.ModifySQL.Add('Adress2 = :OLD_Adress2 and');
  MainModule.UniMainModule.mySQLUpdateSQL1.ModifySQL.Add('Straße = :OLD_Straße and');
  MainModule.UniMainModule.mySQLUpdateSQL1.ModifySQL.Add('PLZ = :OLD_PLZ and');
  MainModule.UniMainModule.mySQLUpdateSQL1.ModifySQL.Add('Ort = :OLD_Ort and');
  MainModule.UniMainModule.mySQLUpdateSQL1.ModifySQL.Add('Land = :OLD_Land and');
  MainModule.UniMainModule.mySQLUpdateSQL1.ModifySQL.Add('Such1 = :OLD_Such1 and');
  MainModule.UniMainModule.mySQLUpdateSQL1.ModifySQL.Add('Such2 = :OLD_Such2');


  search := '%' + UniEdit1.Text + '%';

  fmstart1.UniMemo1.Lines.Clear;
  fmstart1.UniMemo1.Lines.Text := 'select Firma, Adress1, Adress2, Straße, PLZ, Ort, Land, Such1, Such2 from ' + Tabelle + #10 +
                         'where Ident = ' + IntToStr(UniMainModule.Ident) + #10 +
                         'AND (Firma like '+QuotedStr(search)+' OR Adress1 like '+ QuotedStr(search)+' OR Adress2 like '+ QuotedStr(search)+' OR Straße like '+ QuotedStr(search)+ 'OR PLZ like '+ QuotedStr(search)+ 'OR Ort like '+ QuotedStr(search)+ 'OR Land like '+ QuotedStr(search)+ 'OR Such1 like '+ QuotedStr(search)+ 'OR Such2 like '+ QuotedStr(search)+')';

  UniMainModule.mySQLQuery3.SQL.Text := fmstart1.UniMemo1.Lines.Text;
  UniMainModule.mySQLQuery3.Open;

  UniDBGrid1.Columns[0].Width := 250;
  UniDBGrid1.Columns[1].Width := 100;
  UniDBGrid1.Columns[2].Width := 70;
  UniDBGrid1.Columns[3].Width := 150;
  UniDBGrid1.Columns[4].Width := 50;
  UniDBGrid1.Columns[5].Width := 100;
  UniDBGrid1.Columns[6].Width := 100;
  UniDBGrid1.Columns[7].Width := 100;
  UniDBGrid1.Columns[8].Width := 100;
end;

nahpets 28. Okt 2015 17:53

AW: MySQL Query Update funktioniert nicht
 
Vielleicht, weil leere Datenbankfelder nicht = "" sind sondern Null?

Also müsstest Du ggfls. überall auch noch auf
SQL-Code:
or spalte is Null
abfragen?

akio87 28. Okt 2015 18:08

AW: MySQL Query Update funktioniert nicht
 
Ändert sich etwas, wenn ich in der Datenbank die Spalten "Standard" -> "Kein(e)" anpasse und bei "NULL" den haken entferne?

Hab es zwar gerade getestet, scheint so ohne weiteres nicht zu funktionieren...

Spalten auf Null abfragen? Dies bräuchte ich eigentlich dann nur für "Adress1, Adress2, Such1, Such2"...

Wie baut man sowas jetzt da mit ein? So in etwa:

Code:
  MainModule.UniMainModule.mySQLUpdateSQL1.ModifySQL.Add('Adress1 = :Adress1 or spalte is Null');

nahpets 28. Okt 2015 18:11

AW: MySQL Query Update funktioniert nicht
 
jo, genau so, wie in Deinem Beispiel.
Delphi-Quellcode:
  MainModule.UniMainModule.mySQLUpdateSQL1.ModifySQL.Add('Adress1 = :Adress1 or Adress1 is Null');

akio87 28. Okt 2015 18:21

AW: MySQL Query Update funktioniert nicht
 
Klappt nur zu hälfte...

jetzt erscheinen "0" in den leeren Zellen...

Jetzt vielleicht etwas in der Datenbank anpassen?

EDIT:
Updatefunktion geht wieder an den stellen nicht. Es bleibt jetzt "0":

Zitat:


MainModule.UniMainModule.mySQLUpdateSQL1.ModifySQL .Add('update `' + Tabelle + '`');
MainModule.UniMainModule.mySQLUpdateSQL1.ModifySQL .Add('set');
MainModule.UniMainModule.mySQLUpdateSQL1.ModifySQL .Add('Firma = :Firma,');
MainModule.UniMainModule.mySQLUpdateSQL1.ModifySQL .Add('Adress1 = :Adress1 or Adress1 is Null,');
MainModule.UniMainModule.mySQLUpdateSQL1.ModifySQL .Add('Adress2 = :Adress2 or Adress2 is Null,');
MainModule.UniMainModule.mySQLUpdateSQL1.ModifySQL .Add('Straße = :Straße,');
MainModule.UniMainModule.mySQLUpdateSQL1.ModifySQL .Add('PLZ = :PLZ,');
MainModule.UniMainModule.mySQLUpdateSQL1.ModifySQL .Add('Ort = :Ort,');
MainModule.UniMainModule.mySQLUpdateSQL1.ModifySQL .Add('Land = :Land,');
MainModule.UniMainModule.mySQLUpdateSQL1.ModifySQL .Add('Such1 = :Such1 or Such1 is Null,');
MainModule.UniMainModule.mySQLUpdateSQL1.ModifySQL .Add('Such2 = :Such2 or Such2 is Null');
MainModule.UniMainModule.mySQLUpdateSQL1.ModifySQL .Add('where');
MainModule.UniMainModule.mySQLUpdateSQL1.ModifySQL .Add('Firma = :OLD_Firma and');
MainModule.UniMainModule.mySQLUpdateSQL1.ModifySQL .Add('Adress1 = :OLD_Adress1 and');
MainModule.UniMainModule.mySQLUpdateSQL1.ModifySQL .Add('Adress2 = :OLD_Adress2 and');
MainModule.UniMainModule.mySQLUpdateSQL1.ModifySQL .Add('Straße = :OLD_Straße and');
MainModule.UniMainModule.mySQLUpdateSQL1.ModifySQL .Add('PLZ = :OLD_PLZ and');
MainModule.UniMainModule.mySQLUpdateSQL1.ModifySQL .Add('Ort = :OLD_Ort and');
MainModule.UniMainModule.mySQLUpdateSQL1.ModifySQL .Add('Land = :OLD_Land and');
MainModule.UniMainModule.mySQLUpdateSQL1.ModifySQL .Add('Such1 = :OLD_Such1 and');
MainModule.UniMainModule.mySQLUpdateSQL1.ModifySQL .Add('Such2 = :OLD_Such2');

nahpets 28. Okt 2015 18:35

AW: MySQL Query Update funktioniert nicht
 
Sorry, da hab' ich wohl was falsch verstanden oder mich ungeschickt ausgedrückt.
Code:
or spalte is null
gehört nur in die Where-Bedingung aber nicht in den Teil, in dem per Set eine Wertzuweisung erfolgt.

In etwa so:
Delphi-Quellcode:
MainModule.UniMainModule.mySQLUpdateSQL1.ModifySQL .Add('update `' + Tabelle + '`');
MainModule.UniMainModule.mySQLUpdateSQL1.ModifySQL .Add('set');
MainModule.UniMainModule.mySQLUpdateSQL1.ModifySQL .Add('Firma = :Firma,');
MainModule.UniMainModule.mySQLUpdateSQL1.ModifySQL .Add('Adress1 = :Adress1,');
MainModule.UniMainModule.mySQLUpdateSQL1.ModifySQL .Add('Adress2 = :Adress2,');
MainModule.UniMainModule.mySQLUpdateSQL1.ModifySQL .Add('Straße = :Straße,');
MainModule.UniMainModule.mySQLUpdateSQL1.ModifySQL .Add('PLZ = LZ,');
MainModule.UniMainModule.mySQLUpdateSQL1.ModifySQL .Add('Ort = :Ort,');
MainModule.UniMainModule.mySQLUpdateSQL1.ModifySQL .Add('Land = :Land,');
MainModule.UniMainModule.mySQLUpdateSQL1.ModifySQL .Add('Such1 = :Such1,');
MainModule.UniMainModule.mySQLUpdateSQL1.ModifySQL .Add('Such2 = :Such2');
MainModule.UniMainModule.mySQLUpdateSQL1.ModifySQL .Add('where');
MainModule.UniMainModule.mySQLUpdateSQL1.ModifySQL .Add('Firma = :OLD_Firma and');
if :OLD_Adress1 = '' then begin <-- hier natürlich die Variabel abfragen, die dem Parameter :OLD_Adress1 zugewiesen wird.
  MainModule.UniMainModule.mySQLUpdateSQL1.ModifySQL .Add('Adress1 is null and');
end else begin
  MainModule.UniMainModule.mySQLUpdateSQL1.ModifySQL .Add('Adress1 = :OLD_Adress1 and');
end;
if :OLD_Adress2 = '' then begin
  MainModule.UniMainModule.mySQLUpdateSQL1.ModifySQL .Add('Adress2 is null and');
end else begin
  MainModule.UniMainModule.mySQLUpdateSQL1.ModifySQL .Add('Adress2 = :OLD_Adress2 and');
end;
MainModule.UniMainModule.mySQLUpdateSQL1.ModifySQL .Add('Straße = :OLD_Straße and');
MainModule.UniMainModule.mySQLUpdateSQL1.ModifySQL .Add('PLZ = :OLD_PLZ and');
MainModule.UniMainModule.mySQLUpdateSQL1.ModifySQL .Add('Ort = :OLD_Ort and');
MainModule.UniMainModule.mySQLUpdateSQL1.ModifySQL .Add('Land = :OLD_Land and');
if :OLD_Such1 = '' then begin
  MainModule.UniMainModule.mySQLUpdateSQL1.ModifySQL .Add('Such1 = :OLD_Such1 and');
end else begin
  MainModule.UniMainModule.mySQLUpdateSQL1.ModifySQL .Add('Such1 = :OLD_Such1 and');
end;
if :OLD_Such2 = '' then begin
  MainModule.UniMainModule.mySQLUpdateSQL1.ModifySQL .Add('Such2 = :OLD_Such2'); Such2 = :OLD_Such2';
end else begin
  MainModule.UniMainModule.mySQLUpdateSQL1.ModifySQL .Add('Such2 = :OLD_Such2'); Such2 = :OLD_Such2';
end;
Die IF-Abfragen dürfen natürlich nicht auf die Parameter gehen, sondern auf die Variabeln..., deren Werte den Parametern zugewiesen werden.

akio87 28. Okt 2015 19:01

AW: MySQL Query Update funktioniert nicht
 
Liste der Anhänge anzeigen (Anzahl: 1)
Ah herrje, darauf wäre ich ja nie gekommen :D

Die Eingabe erfolgt ja direkt in der UniDBGrid, screenshot im Anhang.
Das heißt, ich muss für die Variable in der IF Anfrage dierekt die Zelle ansprechen?

Code:
if UniDBGrid1.??????? = '' then begin //<-- hier natürlich die Variabel abfragen, die dem Parameter :OLD_Adress1 zugewiesen wird.
  MainModule.UniMainModule.mySQLUpdateSQL1.ModifySQL .Add('Adress1 is null and');
UniDBGrid hat leider keine SelectedField funktion
Code:
DBGrid1.SelectedField.AsString;
Und damit scheint es auch nicht zu funktionieren, bleibt wie gehabt "0" und andere werden dann mit Sntaxfehler angezeigt:
Code:
Query1.FieldByName(Feldname).Asxxx

EDIT: 20:48 Uhr
Hab es nun soweit, dass ich Updaten kann, aber er übernimmt noch immer nicht die Null-Strings:
Code:
MainModule.UniMainModule.mySQLUpdateSQL1.ModifySQL.Clear;
MainModule.UniMainModule.mySQLUpdateSQL1.ModifySQL .Add('update `' + Tabelle + '`');
MainModule.UniMainModule.mySQLUpdateSQL1.ModifySQL .Add('set');
MainModule.UniMainModule.mySQLUpdateSQL1.ModifySQL .Add('Firma = :Firma,');
MainModule.UniMainModule.mySQLUpdateSQL1.ModifySQL .Add('Adress1 = :Adress1,');
MainModule.UniMainModule.mySQLUpdateSQL1.ModifySQL .Add('Adress2 = :Adress2,');
MainModule.UniMainModule.mySQLUpdateSQL1.ModifySQL .Add('Straße = :Straße,');
MainModule.UniMainModule.mySQLUpdateSQL1.ModifySQL .Add('PLZ = :PLZ,');
MainModule.UniMainModule.mySQLUpdateSQL1.ModifySQL .Add('Ort = :Ort,');
MainModule.UniMainModule.mySQLUpdateSQL1.ModifySQL .Add('Land = :Land,');
MainModule.UniMainModule.mySQLUpdateSQL1.ModifySQL .Add('Such1 = :Such1,');
MainModule.UniMainModule.mySQLUpdateSQL1.ModifySQL .Add('Such2 = :Such2');
MainModule.UniMainModule.mySQLUpdateSQL1.ModifySQL .Add('where');
MainModule.UniMainModule.mySQLUpdateSQL1.ModifySQL .Add('Firma = :OLD_Firma and');

if MainModule.UniMainModule.mySQLQuery3.FieldByName('Adress1').AsString = '' then begin //<-- hier natürlich die Variabel abfragen, die dem Parameter :OLD_Adress1 zugewiesen wird.
  MainModule.UniMainModule.mySQLUpdateSQL1.ModifySQL.Add('Adress1 is null and');
end else begin
  MainModule.UniMainModule.mySQLUpdateSQL1.ModifySQL.Add('Adress1 = :OLD_Adress1 and');
end;

if MainModule.UniMainModule.mySQLQuery3.FieldByName('Adress2').AsString = '' then begin
  MainModule.UniMainModule.mySQLUpdateSQL1.ModifySQL.Add('Adress2 is null and');
end else begin
  MainModule.UniMainModule.mySQLUpdateSQL1.ModifySQL.Add('Adress2 = :OLD_Adress2 and');
end;

MainModule.UniMainModule.mySQLUpdateSQL1.ModifySQL.Add('Straße = :OLD_Straße and');
MainModule.UniMainModule.mySQLUpdateSQL1.ModifySQL.Add('PLZ = :OLD_PLZ and');
MainModule.UniMainModule.mySQLUpdateSQL1.ModifySQL.Add('Ort = :OLD_Ort and');
MainModule.UniMainModule.mySQLUpdateSQL1.ModifySQL.Add('Land = :OLD_Land and');

if MainModule.UniMainModule.mySQLQuery3.FieldByName('Such1').AsString = '' then begin
  MainModule.UniMainModule.mySQLUpdateSQL1.ModifySQL.Add('Such1 is null and');
end else begin
  MainModule.UniMainModule.mySQLUpdateSQL1.ModifySQL.Add('Such1 = :OLD_Such1 and');
end;

if MainModule.UniMainModule.mySQLQuery3.FieldByName('Such2').AsString = '' then begin
  MainModule.UniMainModule.mySQLUpdateSQL1.ModifySQL.Add('Such2 is null'); //Such2 = :OLD_Such2';
end else begin
MainModule.UniMainModule.mySQLUpdateSQL1.ModifySQL.Add('Such2 = :OLD_Such2'); //Such2 = :OLD_Such2';
end;

akio87 28. Okt 2015 20:17

AW: MySQL Query Update funktioniert nicht
 
Mir fällt gerade auf, sollte es nicht ehr sorum lauten, wenn ich den neuen Wert als NULL definieren will, wenn der String leer ist?

Code:
MainModule.UniMainModule.mySQLUpdateSQL1.ModifySQL.Clear;
MainModule.UniMainModule.mySQLUpdateSQL1.ModifySQL .Add('update `' + Tabelle + '`');
MainModule.UniMainModule.mySQLUpdateSQL1.ModifySQL .Add('set');
MainModule.UniMainModule.mySQLUpdateSQL1.ModifySQL .Add('Firma = :Firma,');

if :Adress1 = '' then
 begin
   MainModule.UniMainModule.mySQLUpdateSQL1.ModifySQL .Add('Adress1 = NULL,');
 end
else
 begin
   MainModule.UniMainModule.mySQLUpdateSQL1.ModifySQL .Add('Adress1 = :Adress1,');
 end;
Aber wie komme ich an den neuen Wert :Adress1 nach der Eingabe in der DBGrid heran?

Perlsau 28. Okt 2015 20:26

AW: MySQL Query Update funktioniert nicht
 
Ich weiß nicht, ob das auch in MySQL geht, aber in Firebird und MsSQL mache ich das mit den leeren String-Feldern so, daß ich bereits beim Tabellenentwurf das Feld als NotNull deklariere und dann als Defaultwert '' angebe. Damit wird dann beim insert automatisch '' eingetragen, wenn das entsprechende Feld leer (null) ist. Sollte MySQL keinen Defaultwert unterstützen, kannst du den auch in der Query-Komponente angeben.

akio87 28. Okt 2015 20:44

AW: MySQL Query Update funktioniert nicht
 
Liste der Anhänge anzeigen (Anzahl: 1)
ich glaub, ich weiß was Du meinst.

Ich hab das mal ein Screenshot im Anhang beigelegt.
Es ändert sich bei keiner Einstellungsvariante etwas daran, dass wenn der Wert in der DBGrid LEER ist, dass es so in die DB übertragen wird. Es bleibt der alte Wert bestehen.

Im INSERT Befehl geht es ja auch leeren Strings, aber im UPDATE nicht...

Perlsau 28. Okt 2015 22:02

AW: MySQL Query Update funktioniert nicht
 
Die meisten Datenbanken – zumindest alle, die ich schonmal ausprobiert habe – führen beim Update und Insert ein Trim auf Strings (VarChar) durch. Das heißt, wenn am Anfang oder Ende des Strings ein Leerzeichen steht, wird das vor dem Eintrag in die Tabelle entfernt. Vielleicht könntest du diese Eigenschaft nutzen, indem du, wenn du beim Update den Inhalt eines VarChar-Feldes löschen willst, einfach ein Leerzeichen übergibst.

Was mir jetzt gerade beim Schreiben dieser Zeilen einfällt: Versuche doch einmal, den Leerstring, den du eintragen möchtest, zu quoten:
Delphi-Quellcode:
Leerstring := QuotedStr('');
... dasselbe solltest du auch mit einem Leerzeichen tun, das du eintragen möchtest, falls das mit dem Leerstring nicht funktioniert. Grundsätzlich müssen Strings ja gequotet werden, bevor man sie in die DB überträgt. Gilt aber nicht für die Verwendung von Parametern, soweit ich weiß ...

akio87 29. Okt 2015 08:17

AW: MySQL Query Update funktioniert nicht
 
Hallo,

das QuoteStr() kenne ich, aber leider wird die Eingabe direkt in der DBGrid stattfinden und mit der Query geupdatet. Wie sollte ich das in der DQL Sprache umsetzen, wenn ich dies in die ModifySQL.Add() übergeben will? Da ich die Eingabe in der DBGrid vorher nicht in einem String lade.

Alternativ habe ich soeben fogendes gefunden:
Eine IF THEN direkt in der SQL Query... Kann ich das nicht irgendwie verwenden?

Code:
UPDATE table
SET columnB = CASE fieldA
        WHEN columnA=1 THEN 'x'
        WHEN columnA=2 THEN 'y'
        ELSE 'z'
      END
WHERE columnC = 1

Vielleicht in meinem Beispiel in etwa so:
Code:
MainModule.UniMainModule.mySQLUpdateSQL1.ModifySQL.Clear;
MainModule.UniMainModule.mySQLUpdateSQL1.ModifySQL.Add('update `' + Tabelle + '`');
MainModule.UniMainModule.mySQLUpdateSQL1.ModifySQL.Add('set');
MainModule.UniMainModule.mySQLUpdateSQL1.ModifySQL.Add('Firma = :Firma,');
MainModule.UniMainModule.mySQLUpdateSQL1.ModifySQL.Add('Adress1 = Case WHEN :Adress1 = '' THEN Adress1 = NULL ELSE Adress1 = :Adress1'); // <--- ODER Adress1 = TRIM(:Adress1)??
MainModule.UniMainModule.mySQLUpdateSQL1.ModifySQL.Add('Adress2 = Case WHEN :Adress2 = '' THEN Adress2 = NULL ELSE Adress2 = :Adress2');
//Komma Reglung irgendwie mit dazu packen? :D
...

Lemmy 29. Okt 2015 08:51

AW: MySQL Query Update funktioniert nicht
 
Zitat:

Zitat von Perlsau (Beitrag 1320044)
Die meisten Datenbanken – zumindest alle, die ich schonmal ausprobiert habe – führen beim Update und Insert ein Trim auf Strings (VarChar) durch.

Ich denke du bringst hier gehörig was durcheinander. Ein solches Verhalten eines DBMS (die im übergebenen Daten selbst zu ändern) würde zu sofortigem Deinstallieren und zu einem 10 Jahres Bann (zumindest in meiner Umgebung) führen. Zumindest für Firebird (2.1) und MySQL (5.1) gilt das von dir beschriebene Verhalten nicht.

Was mich bei der ganzen Diskussion die ganze Zeit etwas irritiert: Warum fummelst du manuell im Modify-SQL herum? Welche Komponentenlib verwendest Du denn hier?
Wenn Du ein "normales" TQUery/TUpdateSQL Gespann hast, dann sollte das Zusammenbauen der notwendigen SQLs (Zuweisung Parameter usw) von allein ablaufen.

Und warum hast du in deiner Tabelle eigentlich keinen PrimaryKey definiert? Damit sollte sich die Identifizierung des Datensatzes und damit die nicht zu überschauende WHERE Bedingung erledigen....

p80286 29. Okt 2015 09:09

AW: MySQL Query Update funktioniert nicht
 
Zitat:

Zitat von Lemmy (Beitrag 1320073)
Und warum hast du in deiner Tabelle eigentlich keinen PrimaryKey definiert? Damit sollte sich die Identifizierung des Datensatzes und damit die nicht zu überschauende WHERE Bedingung erledigen....

Das hast Du falsch verstanden, das ist "security by obscurity". Stell dir vor wie simpel es wäre eine Gridzeile zu lesen und daraus ein Updatestatement zu generieren. Das könnte ja jeder verstehen.
Und eine eindeutige ID, da würde ja garantiert nur ein Datensatz geändert.

Gruß
K-H

akio87 29. Okt 2015 09:16

AW: MySQL Query Update funktioniert nicht
 
Die verwendete TMySQLUpdateSQL Komponente kann ich so nicht nutzen.

Der Aufbau erfolgt über eine DBGrid mit zwei Tabellen (Rechnungsadressen und Lieferadressen), welche ich im Vorfeld wärhrend der Laufzeit festlege, welche ich nun verwalten will. Also muss ich das Quellcode bezogen definieren und nicht in der Komoponente festlegen, da dort eine Feste Tabelle angegeben werden muss.

Ich bräuchte also eine Lösung, wie angesprochen. Wäre den die IF Then Variante ein Ansatz und wie schreibt man das richtig in einem SQL Query Befehl um?

Lemmy 29. Okt 2015 09:18

AW: MySQL Query Update funktioniert nicht
 
Zitat:

Zitat von p80286 (Beitrag 1320077)
Zitat:

Zitat von Lemmy (Beitrag 1320073)
Und warum hast du in deiner Tabelle eigentlich keinen PrimaryKey definiert? Damit sollte sich die Identifizierung des Datensatzes und damit die nicht zu überschauende WHERE Bedingung erledigen....

Das hast Du falsch verstanden, das ist "security by obscurity". Stell dir vor wie simpel es wäre eine Gridzeile zu lesen und daraus ein Updatestatement zu generieren. Das könnte ja jeder verstehen.


aha... ich seh schon. ich bin für die realen Probleme diese Welt zu einfach gestrickt....
oder
Zitat:

Ich bin zu alt für diesen Scheiß...
;-)

Lemmy 29. Okt 2015 09:30

AW: MySQL Query Update funktioniert nicht
 
Zitat:

Zitat von akio87 (Beitrag 1320080)
Der Aufbau erfolgt über eine DBGrid mit zwei Tabellen (Rechnungsadressen und Lieferadressen), welche ich im Vorfeld wärhrend der Laufzeit festlege, welche ich nun verwalten will.

Warum dann nicht 2 Queries, 2 UpdateSQL, 2 DataSources und zur Laufzeit änderst Du lediglich die Datasource-Eigenschaft des Grids?

akio87 29. Okt 2015 10:40

AW: MySQL Query Update funktioniert nicht
 
die Umstellung zieht ein Rattenschwanz mit sich - ich seh das schon kommen..

Ich teste die funktionalität mit einer DBGrid und lass die TmySQLUpdateSQL ihren eigenen Job erledigen.
Mal schauen, ob er die Null/Leer Strings in der DBGrid-Zelle erfolgreich in die DB speichert...

Wenn das auch nicht funktioniert, find ich den Ansatz mit der WHEN THEN immernoch als gute alternative, wenn man es richtig umsetzten kann. Ob die Schreibweise so richtig ist, teste ich dann ebenfalls.
Code:
MainModule.UniMainModule.mySQLUpdateSQL1.ModifySQL.Add('Adress1 = Case WHEN :Adress1 = '' THEN Adress1 = NULL ELSE Adress1 = :Adress1'); // <--- ODER Adress1 = TRIM(:Adress1)??
MainModule.UniMainModule.mySQLUpdateSQL1.ModifySQL.Add('Adress2 = Case WHEN :Adress2 = '' THEN Adress2 = NULL ELSE Adress2 = :Adress2');
Erst einmal vielen Dank an Alle. Bis heute Abend.

Perlsau 29. Okt 2015 11:22

AW: MySQL Query Update funktioniert nicht
 
Zitat:

Zitat von Lemmy (Beitrag 1320073)
Zitat:

Zitat von Perlsau (Beitrag 1320044)
Die meisten Datenbanken – zumindest alle, die ich schonmal ausprobiert habe – führen beim Update und Insert ein Trim auf Strings (VarChar) durch.

Ich denke du bringst hier gehörig was durcheinander. Ein solches Verhalten eines DBMS (die im übergebenen Daten selbst zu ändern) würde zu sofortigem Deinstallieren und zu einem 10 Jahres Bann (zumindest in meiner Umgebung) führen. Zumindest für Firebird (2.1) und MySQL (5.1) gilt das von dir beschriebene Verhalten nicht.

Hab's gerade eben nochmal getestet:
  • In einer Anwendung in einem DBEdit, das auf ein VarChar-Feld verweist, ein Leerzeichen am Ende des Strings angefügt: Leerzeichen bleibt erhalten.
  • Im IbExpert in derselben DB im selben Record und derselben Spalte ein Leerzeichen ans Ende des Strings gesetzt: Leerzeichen wird beim Posten entfernt.

Da hab ich also in der Tat was durcheinandergebracht, nehme alles zurück und behaupte das Gegenteil :stupid:

Lemmy 29. Okt 2015 11:54

AW: MySQL Query Update funktioniert nicht
 
Zitat:

Zitat von Perlsau (Beitrag 1320104)
  • Im IbExpert in derselben DB im selben Record und derselben Spalte ein Leerzeichen ans Ende des Strings gesetzt: Leerzeichen wird beim Posten entfernt.

Das ist aber ein Problem von IBExpert und nicht von Firebird: Das Leerzeichen wird lediglich in der Gridanzeige entfernt! In der Datenbank bleibt das weiterhin enthalten.
Beispiel: Steht " das " in der Spalte, wird char_length korrekt mit 5 ermittelt, in der Grid-Anzeige fehlt aber das letzte Leerzeichen. Hänge ich nun weitere Leerzeichen per IBExpert-Grid ran, dann bleibt das so bei den 5. Ändere ich das per Update SQL, wird der Text so abgespeichert wie ich will und nicht wie IBExpert meint dass es sein müsste... und es ändert sich auch die String-Länge (Hinweis IBExpert 2015.1.11.1)

hoika 31. Okt 2015 06:18

AW: MySQL Query Update funktioniert nicht
 
Hallo,
wenn mich nicht alles täuscht, ist das Trim eine Konfigurations-Option von IB-Expert.

Heiko

BadenPower 31. Okt 2015 13:08

AW: MySQL Query Update funktioniert nicht
 
Zitat:

Zitat von akio87 (Beitrag 1320005)
ich habe festgestellt, dass meine alte Update Funktion, siehe 2. Code, in der BDGrid mit einem Leerem String nicht funktioniert. In der neuen Variante, wo ich dachte, das es dort geht, funktioniert der leere String ebenfalls nicht + Update generell nicht, mit folgender Fehlermeldung:
Error: SQL Syntax...

Habt ihr eine Idee?

Für diese Problem habe ich mir spezielle Funktionen geschrieben, welche die Statements automatisch und unabhängig von der jeweils verwendeten Tabelle erstellen.

Die Funktionen berücksichtigen auch, dass in den Komponenten enthaltenen NULL-Wert des Feldes, welcher dann wahlweise als NULL oder als Leerstring übergeben werden kann.

Delphi-Quellcode:
unit uDataModuleDB;

interface

uses
  SysUtils, Classes, Forms, Dialogs, Variants, DB,
  ZConnection, ZAbstractTable, ZDataset, ZAbstractRODataset,
  ZAbstractDataset, ZSqlProcessor, ZSqlMonitor;

type
  TDMDb = class(TDataModule)
  public
    function GenerateZUpdateSQLInsert(ATable: TZTable): String; overload;
    function GenerateZUpdateSQLInsert(ATable: TZTable; ANullAsString: Boolean): String; overload;
    function GenerateZUpdateSQLModify(ATable: TZTable): String; overload;
    function GenerateZUpdateSQLModify(ATable: TZTable; ANullAsString: Boolean): String; overload;
    function GenerateZUpdateSQLDelete(ATable: TZTable): String; overload;
    function GenerateZUpdateSQLDelete(ATable: TZTable; ANullAsString: Boolean): String; overload;
    function GenerateZTableSQLSelectOldValues(ATable: TZTable): String;
    function GenerateZTableSQLSelectCountOldValues(ATable: TZTable): String;
    function GenerateZTableSQLWhereOldValues(ATable: TZTable): String;


  end;

var
  DMDb: TDMDb;

implementation

function TDMDb.GenerateZTableSQLWhereOldValues(ATable: TZTable): string;
var
  liZ1: integer;
  lSQLWhere: String;
begin
  lSQLWhere := '';

  for liZ1 := 0 to ATable.FieldCount - 1 do
   begin
    if (liZ1 > 0) then
     begin
      lSQLWhere := lSQLWhere + ' AND ';
     end;
    lSQLWhere := lSQLWhere + '(';
    if(VarIsNull(ATable.Fields[liZ1].OldValue)) then
     begin
      lSQLWhere := lSQLWhere + '(';
     end;
    lSQLWhere := lSQLWhere + ATable.Fields[liZ1].FieldName + ' = ' + ':OLD_' + ATable.Fields[liZ1].FieldName;
    if(VarIsNull(ATable.Fields[liZ1].OldValue)) then
     begin
      lSQLWhere := lSQLWhere + ')';
      lSQLWhere := lSQLWhere + ' OR (' + ATable.Fields[liZ1].FieldName + ' IS NULL )';
      lSQLWhere := lSQLWhere + ' OR (' + ATable.Fields[liZ1].FieldName + ' = 0 )';
     end;
    lSQLWhere := lSQLWhere + ')';
   end;

  if (lSQLWhere <> '') then
   begin
    lSQLWhere := ' WHERE ' + lSQLWhere;
   end;

  Result := lSQLWhere;
end;

function TDMDb.GenerateZUpdateSQLInsert(ATable: TZTable): string;
begin
  Result := GenerateZUpdateSQLInsert(ATable,true);
end;

function TDMDb.GenerateZUpdateSQLInsert(ATable: TZTable; ANullAsString: boolean): string;
var
  liZ1: integer;
  lSQL: String;
  lSQLFields: String;
  lSQLValues: String;
begin
  lSQLFields := '';
  lSQLValues := '';
  lSQL := 'INSERT INTO ' + ATable.TableName;
  for liZ1 := 0 to ATable.FieldCount - 1 do
   begin
    if (liZ1 > 0) then
     begin
      lSQLFields := lSQLFields + ' , ';
      lSQLValues := lSQLValues + ' , ';
     end;
    lSQLFields := lSQLFields + ATable.Fields[liZ1].FieldName;
    if (     (ANullAsString)
         and (ATable.Fields[liZ1].DataType in [ftString,ftMemo,ftFmtMemo,ftFixedChar,ftWideString,ftFixedWideChar,ftWideMemo])
         and (VarToStr(ATable.Fields[liZ1].Value) = '')
       ) then
     begin
      lSQLValues := lSQLValues + '''' + '''';
     end
    else
     begin
      lSQLValues := lSQLValues + ':' + ATable.Fields[liZ1].FieldName;
     end;
   end;
  lSQL := lSQL + ' (' + lSQLFields + ') VALUES (' + lSQLValues + ')';
  Result := lSQL + ';';

end;

function TDMDb.GenerateZUpdateSQLModify(ATable: TZTable): string;
begin
  Result := GenerateZUpdateSQLModify(ATable,true);
end;

function TDMDb.GenerateZUpdateSQLModify(ATable: TZTable; ANullAsString: boolean): string;
var
  liZ1: integer;
  lSQL: String;
  lSQLWhere: String;
begin

  lSQL := 'UPDATE ' + ATable.TableName + ' SET ';
  for liZ1 := 0 to ATable.FieldCount - 1 do
   begin
    if (liZ1 > 0) then
     begin
      lSQL := lSQL + ' , ';
     end;

    lSQL := lSQL + ATable.Fields[liZ1].FieldName + ' = ';
    if (     (ANullAsString)
         and (ATable.Fields[liZ1].DataType in [ftString,ftMemo,ftFmtMemo,ftFixedChar,ftWideString,ftFixedWideChar,ftWideMemo])
         and (VarToStr(ATable.Fields[liZ1].Value) = '')
       ) then
     begin
      lSQL := lSQL + '''' + '''';
     end
    else
     begin
      lSQL := lSQL + ':' + ATable.Fields[liZ1].FieldName;
     end;

   end;
  lSQLWhere := GenerateZTableSQLWhereOldValues(ATable);
  Result := lSQL + lSQLWhere + ';';

end;

function TDMDb.GenerateZUpdateSQLDelete(ATable: TZTable): string;
begin
  Result := GenerateZUpdateSQLDelete(ATable,true);
end;

function TDMDb.GenerateZUpdateSQLDelete(ATable: TZTable; ANullAsString: boolean): string;
var
  lSQL: String;
  lSQLWhere: String;
begin
  lSQL := 'DELETE FROM ' + ATable.TableName;
  lSQLWhere := GenerateZTableSQLWhereOldValues(ATable);
  Result := lSQL + lSQLWhere + ';';
end;

end;
Der Aufruf und das Generieren der Statements erfolgt dann in der Update-Komponente in den jeweiligen Events OnBeforeDelete, OnBeforeInsert und OnBeforeModify:

Delphi-Quellcode:
procedure TF_Data.ZUPS_TableBeforeDeleteSQL(Sender: TObject);
begin
  ZUPS_Table.DeleteSQL.Text := DMDb.GenerateZUpdateSQLDelete(ZT_Table);
end;

procedure TF_Data.ZUPS_TableBeforeInsertSQL(Sender: TObject);
begin
  ZUPS_Table.InsertSQL.Text := DMDb.GenerateZUpdateSQLInsert(ZT_Table);
end;

procedure TF_Data.ZUPS_TableBeforeModifySQL(Sender: TObject);
begin
  ZUPS_Table.ModifySQL.Text := DMDb.GenerateZUpdateSQLModify(ZT_Table);
end;
Ich hoffe das hilft Dir weiter.

Dejan Vu 2. Nov 2015 07:05

AW: MySQL Query Update funktioniert nicht
 
Sehr schön, das Du die 'hässliche' Generierung der SQL-Befehle so versteckst. Das schafft Übersicht.

Zwei Anmerkungen:
1. Wieso deklarierst du nicht einfach ein Feld als 'PK', dann kannst Du dir das 'WhereOldValues' sparen?
2. Deine NULL-Behandlung sieht (auf den ersten Blick beim Frühstück) etwas wackelig aus. Du behandelst '0' als NULL-Äquivalent, aber den leeren String nicht? :gruebel:

BadenPower 2. Nov 2015 10:00

AW: MySQL Query Update funktioniert nicht
 
Zitat:

Zitat von Dejan Vu (Beitrag 1320312)
Sehr schön, das Du die 'hässliche' Generierung der SQL-Befehle so versteckst. Das schafft Übersicht.

Wieso verstecken?
Das sind Grundfunktionen und für jede Tabelle ausführbar und gehören daher zur Übersichtlichkeit des Quellcodes in separate Funktionen.

Zitat:

Zitat von Dejan Vu (Beitrag 1320312)
1. Wieso deklarierst du nicht einfach ein Feld als 'PK', dann kannst Du dir das 'WhereOldValues' sparen?

Man sollte etwas über den Tellerrand hinausschauen und dann würde man feststellen, dass ein PK nicht das leistet, was die Generierung dieses SQL-Statements leistet.

Durch das SQL-Statement ist gewährleistet, dass der Datensatz nur geändert wird, wenn zwischenzeitlich keine Änderungen des Datensatzes durch z.B einen anderen User durchgeführt wurden.

Der PK "erkennt" dies ja nicht.

Zitat:

Zitat von Dejan Vu (Beitrag 1320312)
2. Deine NULL-Behandlung sieht (auf den ersten Blick beim Frühstück) etwas wackelig aus. Du behandelst '0' als NULL-Äquivalent, aber den leeren String nicht? :gruebel:

Weil dies nicht notwendig ist.

Sir Rufo 2. Nov 2015 15:35

AW: MySQL Query Update funktioniert nicht
 
Um Concurrent Conflicts zu erkennen würde auch ein Feld mit der RowVersion reichen. :stupid:

BadenPower 2. Nov 2015 16:33

AW: MySQL Query Update funktioniert nicht
 
Zitat:

Zitat von Sir Rufo (Beitrag 1320355)
Um Concurrent Conflicts zu erkennen würde auch ein Feld mit der RowVersion reichen. :stupid:

Wenn Du die Datenbank-Struktur in der eigenen Hand hast, dann ja.

Weitere Vorraussetzung wäre dann auch noch, dass nur Deine Software auf die Datenbank zugreift, oder dass auch alle anderen Entwicklungen, welche auf die Tabelle zugreifen, dieses Feld beschreiben.


Alle Zeitangaben in WEZ +1. Es ist jetzt 07:44 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz