Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Datenbanken (https://www.delphipraxis.net/15-datenbanken/)
-   -   Mehrfach Update STatement (https://www.delphipraxis.net/201259-mehrfach-update-statement.html)

Ykcim 5. Jul 2019 13:32

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

Mehrfach Update STatement
 
Hallo Zusammen,

ich versuche mich gerade an einem Statement, mit dem ich mehrere Zeilen (hier im Beispiel 3 Zeilen) mit jeweil 3 Werten updaten möchte. Wenn ich das mit einzelnen SQL-Statements mache, wird die Procedure sehr langsam.

Folgendes habe ich gefunden, bzw. auf meinen Fall umgebaut:
Delphi-Quellcode:
update as400 set
  sequence = case
      when concat(waaunr,'-',waaupo) ='408216-0' and oaagnr =10 then 1
      when concat(waaunr,'-',waaupo) ='408217-0' and oaagnr =10 then 2
      when concat(waaunr,'-',waaupo) ='408218-0' and oaagnr =10 then 3
  end,
  frozen = case
      when concat(waaunr,'-',waaupo) ='408216-0' and oaagnr =10 then 1
      when concat(waaunr,'-',waaupo) ='408217-0' and oaagnr =10 then 1
      when concat(waaunr,'-',waaupo) ='408218-0' and oaagnr =10 then 0
  end,
  plan_date = case
      when concat(waaunr,'-',waaupo) ='408216-0' and oaagnr =10 then '2019-07-05'
      when concat(waaunr,'-',waaupo) ='408217-0' and oaagnr =10 then '2019-07-05'
      when concat(waaunr,'-',waaupo) ='408218-0' and oaagnr =10 then '2019-07-06'
  end
where concat(waaunr,'-',waaupo) in ('408216-0', '408217-0', '408218-0')
Aber leider habe ich das Problem, dass ich die Fehlermeldung "Column 'sequence' cannot be null" bekomme.

Wenn ich das richtig sehe, wird der Wert für die Spalten nicht erkannt.

Sieht jemand was ich falsch mache und kann mir jemand einen Tip geben?

Vielen Dank
Patrick

hoika 5. Jul 2019 14:07

AW: Mehrfach Update STatement
 
Hallo,
fehlt vielleicht ein else?

Ykcim 5. Jul 2019 14:13

AW: Mehrfach Update STatement
 
Ich habe soeben herausgefunden, dass es an den zwei Bedingungen liegt
Delphi-Quellcode:
when concat(waaunr,'-',waaupo) ='408216-0' and oaagnr ='10' then '1'
Hier mach er den Fehler

Delphi-Quellcode:
when concat(waaunr,'-',waaupo) ='408216-0' then '1'
Hier macht er den Fehler nicht.

Leider hilft es nicht, wenn ich eine Klammer um die beiden Bedingungen mache...
Delphi-Quellcode:
update as400 set
  sequence = case
      when (concat(waaunr,'-',waaupo) =408216-0 and oaagnr =10) then 1
      when (concat(waaunr,'-',waaupo) =408217-0 and oaagnr =10) then 2
      when (concat(waaunr,'-',waaupo) =408218-0 and oaagnr =10) then 3
  end,
  frozen = case
      when (concat(waaunr,'-',waaupo) =408216-0 and oaagnr =10) then 1
      when (concat(waaunr,'-',waaupo) =408217-0 and oaagnr =10) then 1
      when (concat(waaunr,'-',waaupo) =408218-0 and oaagnr =10) then 0
  end,
  plan_date = case
      when (concat(waaunr,'-',waaupo) =408216-0 and oaagnr =10) then '2019-07-05'
      when (concat(waaunr,'-',waaupo) =408217-0 and oaagnr =10) then '2019-07-05'
      when (concat(waaunr,'-',waaupo) =408218-0 and oaagnr =10) then '2019-07-06'
  end
where concat(waaunr,'-',waaupo) in (408216-0, 408217-0, 408218-0)
Hat jemand dazu eine Idee?

Vielen Dank
Patrick

hoika 5. Jul 2019 14:47

AW: Mehrfach Update STatement
 
Hallo,
welchen Fehler, diesen SQL-Fehler von oben?

oben steht
and oaagnr =10

und unten

and oaagnr ="10"

Welchen Datentyp hat oaagnr?

Ykcim 5. Jul 2019 14:49

AW: Mehrfach Update STatement
 
Ja, immernoch der Fehler: Column 'sequence' cannot be null

Habe oben auch noch die Lösung mit den Klammern hinzugefügt, die leider den gleichen Fehler ergibt...

Ich suche einen Weg, zwei Bedingungen in dem WHEN-Statement unter zu bekommen. Nehme ich das zweite (oaagnr=10) raus, funktioniert es...

hoika 5. Jul 2019 14:51

AW: Mehrfach Update STatement
 
Hallo,
zeig mal deine Klammern-Lösung.

Ykcim 5. Jul 2019 14:52

AW: Mehrfach Update STatement
 
OAAGNR ist ein Integer. Ich versuche gerade alle Varianten, die ich finden kann, daher der versehentliche Unterschied....

Die Fehlermeldung bleibt aber immer die gleiche
Column 'sequence' cannot be null

Ykcim 5. Jul 2019 14:52

AW: Mehrfach Update STatement
 
Delphi-Quellcode:
update as400 set
  sequence = case
      when (concat(waaunr,'-',waaupo) =408216-0 and oaagnr =10) then 1
      when (concat(waaunr,'-',waaupo) =408217-0 and oaagnr =10) then 2
      when (concat(waaunr,'-',waaupo) =408218-0 and oaagnr =10) then 3
  end,
  frozen = case
      when (concat(waaunr,'-',waaupo) =408216-0 and oaagnr =10) then 1
      when (concat(waaunr,'-',waaupo) =408217-0 and oaagnr =10) then 1
      when (concat(waaunr,'-',waaupo) =408218-0 and oaagnr =10) then 0
  end,
  plan_date = case
      when (concat(waaunr,'-',waaupo) =408216-0 and oaagnr =10) then '2019-07-05'
      when (concat(waaunr,'-',waaupo) =408217-0 and oaagnr =10) then '2019-07-05'
      when (concat(waaunr,'-',waaupo) =408218-0 and oaagnr =10) then '2019-07-06'
  end
where concat(waaunr,'-',waaupo) in (408216-0, 408217-0, 408218-0)

hoika 5. Jul 2019 14:58

AW: Mehrfach Update STatement
 
Hallo,
when concat(waaunr,'-',waaupo) ='408216-0' and oaagnr =1 then '1'

Du hast bei 408216-0 die Hochkommas vergessen.

Ykcim 5. Jul 2019 15:01

AW: Mehrfach Update STatement
 
Ich habe es jetzt so:
Delphi-Quellcode:
update as400 set
  sequence = case
      when (concat(waaunr,'-',waaupo) ='408216-0' and oaagnr =10) then '1'
      when (concat(waaunr,'-',waaupo) ='408217-0' and oaagnr =10) then '2'
      when (concat(waaunr,'-',waaupo) ='408218-0' and oaagnr =10) then '3'
  end,
  frozen = case
      when (concat(waaunr,'-',waaupo) ='408216-0' and oaagnr =10) then '1'
      when (concat(waaunr,'-',waaupo) ='408217-0' and oaagnr =10) then '1'
      when (concat(waaunr,'-',waaupo) ='408218-0' and oaagnr =10) then '0'
  end,
  plan_date = case
      when (concat(waaunr,'-',waaupo) ='408216-0' and oaagnr =10) then '2019-07-05'
      when (concat(waaunr,'-',waaupo) ='408217-0' and oaagnr =10) then '2019-07-05'
      when (concat(waaunr,'-',waaupo) ='408218-0' and oaagnr =10) then '2019-07-06'
  end
where concat(waaunr,'-',waaupo) in ('408216-0', '408217-0', '408218-0')
und so versucht
Delphi-Quellcode:
update as400 set
  sequence = case
      when (concat(waaunr,'-',waaupo) ='408216-0' and oaagnr =10) then 1
      when (concat(waaunr,'-',waaupo) ='408217-0' and oaagnr =10) then 2
      when (concat(waaunr,'-',waaupo) ='408218-0' and oaagnr =10) then 3
  end,
  frozen = case
      when (concat(waaunr,'-',waaupo) ='408216-0' and oaagnr =10) then 1
      when (concat(waaunr,'-',waaupo) ='408217-0' and oaagnr =10) then 1
      when (concat(waaunr,'-',waaupo) ='408218-0' and oaagnr =10) then 0
  end,
  plan_date = case
      when (concat(waaunr,'-',waaupo) ='408216-0' and oaagnr =10) then '2019-07-05'
      when (concat(waaunr,'-',waaupo) ='408217-0' and oaagnr =10) then '2019-07-05'
      when (concat(waaunr,'-',waaupo) ='408218-0' and oaagnr =10) then '2019-07-06'
  end
where concat(waaunr,'-',waaupo) in ('408216-0', '408217-0', '408218-0')
und so
Delphi-Quellcode:
update as400 set
  sequence = case
      when concat(waaunr,'-',waaupo) ='408216-0' and oaagnr =10 then 1
      when concat(waaunr,'-',waaupo) ='408217-0' and oaagnr =10 then 2
      when concat(waaunr,'-',waaupo) ='408218-0' and oaagnr =10 then 3
  end,
  frozen = case
      when concat(waaunr,'-',waaupo) ='408216-0' and oaagnr =10 then 1
      when concat(waaunr,'-',waaupo) ='408217-0' and oaagnr =10 then 1
      when concat(waaunr,'-',waaupo) ='408218-0' and oaagnr =10 then 0
  end,
  plan_date = case
      when concat(waaunr,'-',waaupo) ='408216-0' and oaagnr =10 then '2019-07-05'
      when concat(waaunr,'-',waaupo) ='408217-0' and oaagnr =10 then '2019-07-05'
      when concat(waaunr,'-',waaupo) ='408218-0' and oaagnr =10 then '2019-07-06'
  end
where concat(waaunr,'-',waaupo) in ('408216-0', '408217-0', '408218-0')
Leider ist die Fehlermeldung immer die gleiche: Column 'sequence' cannot be null

hoika 5. Jul 2019 15:08

AW: Mehrfach Update STatement
 
Hallo,
was ist, wenn keines deiner 3 when zuschlägt.
Ich bin der Meinung, dass eine else fehlt.
Dein Feld sequenze ist doch bestimmt als not null gekennzeichnet oder ?

Ykcim 5. Jul 2019 15:11

AW: Mehrfach Update STatement
 
Ja, das Feld ist als not null definiert. Aber die Abfrage müsste Matchen, so dass mir ein Else vielleicht die Fehlermeldung eliminieret, aber mir nicht das Update durchführt…

Ykcim 5. Jul 2019 15:19

AW: Mehrfach Update STatement
 
Liste der Anhänge anzeigen (Anzahl: 2)
Ich habe jetzt ein Else eingebaut und es hat einen Teilerfolg gebracht:
Delphi-Quellcode:
update as400 set
  sequence = case
      when (concat(waaunr,'-',waaupo) ='408216-0' and oaagnr =20) then 1
      when (concat(waaunr,'-',waaupo) ='408217-0' and oaagnr =20) then 2
      when (concat(waaunr,'-',waaupo) ='408218-0' and oaagnr =20) then 3
      else 0
  end,
  frozen = case
      when (concat(waaunr,'-',waaupo) ='408216-0' and oaagnr =20) then 1
      when (concat(waaunr,'-',waaupo) ='408217-0' and oaagnr =20) then 1
      when (concat(waaunr,'-',waaupo) ='408218-0' and oaagnr =20) then 0
      else 0
  end,
  plan_date = case
      when (concat(waaunr,'-',waaupo) ='408216-0' and oaagnr =20) then '2019-07-05'
      when (concat(waaunr,'-',waaupo) ='408217-0' and oaagnr =20) then '2019-07-05'
      when (concat(waaunr,'-',waaupo) ='408218-0' and oaagnr =20) then '2019-07-06'
      else '000-00-00'
  end
where concat(waaunr,'-',waaupo) in ('408216-0', '408217-0', '408218-0')
Jetzt wird tatsächlich die Daten eingetragen, aber bei allen anderen Arbeitsgängen (nach 10 kommt 20, 30 usw) greift dann das ELSE.

das bedeutet, dass die vorhergehenden Daten, die unangetastet bleiben sollen, mit dem ELSE überschrieben werden...

Ich habe es in zwei Screenshots dargestellt...

Ykcim 5. Jul 2019 15:32

AW: Mehrfach Update STatement
 
Vielleicht habe ich eine Möglichkeit gefunden, wie ich das Problem umgehen kann. Ich packe das zweite Feld als concat in die letzte WHERE-Klausel mit rein, dann scheint es zu funktionieren. Das sieht zwar nicht so schön aus, in sofern bin ich für Vorschläge sehr offen...
Delphi-Quellcode:
update as400 set
  sequence = case
      when (concat(waaunr,'-',waaupo) ='408216-0' and oaagnr =10) then 1
      when (concat(waaunr,'-',waaupo) ='408217-0' and oaagnr =10) then 2
      when (concat(waaunr,'-',waaupo) ='408218-0' and oaagnr =10) then 3
      else 0
  end,
  frozen = case
      when (concat(waaunr,'-',waaupo) ='408216-0' and oaagnr =10) then 1
      when (concat(waaunr,'-',waaupo) ='408217-0' and oaagnr =10) then 1
      when (concat(waaunr,'-',waaupo) ='408218-0' and oaagnr =10) then 0
      else 0
  end,
  plan_date = case
      when (concat(waaunr,'-',waaupo) ='408216-0' and oaagnr =10) then '2019-07-05'
      when (concat(waaunr,'-',waaupo) ='408217-0' and oaagnr =10) then '2019-07-05'
      when (concat(waaunr,'-',waaupo) ='408218-0' and oaagnr =10) then '2019-07-06'
      else '000-00-00'
  end
where concat(waaunr,'-',waaupo,'-',oaagnr) in ('408216-0-10', '408217-0-10', '408218-0-10')
Vielen Dank
Patrick

hoika 5. Jul 2019 16:13

AW: Mehrfach Update STatement
 
Puh,
und das kurz vorm Wochenende.

Aber wenn es geht, ist doch gut.

Ykcim 5. Jul 2019 17:04

AW: Mehrfach Update STatement
 
Vielen Dank für die Unterstützung.
Schönes Wochenende

peterbelow 6. Jul 2019 11:17

AW: Mehrfach Update STatement
 
Zitat:

Zitat von Ykcim (Beitrag 1436080)
Hallo Zusammen,

ich versuche mich gerade an einem Statement, mit dem ich mehrere Zeilen (hier im Beispiel 3 Zeilen) mit jeweil 3 Werten updaten möchte. Wenn ich das mit einzelnen SQL-Statements mache, wird die Procedure sehr langsam.

Folgendes habe ich gefunden, bzw. auf meinen Fall umgebaut:
Delphi-Quellcode:
update as400 set
  sequence = case
      when concat(waaunr,'-',waaupo) ='408216-0' and oaagnr =10 then 1
      when concat(waaunr,'-',waaupo) ='408217-0' and oaagnr =10 then 2
      when concat(waaunr,'-',waaupo) ='408218-0' and oaagnr =10 then 3
  end,
  frozen = case
      when concat(waaunr,'-',waaupo) ='408216-0' and oaagnr =10 then 1
      when concat(waaunr,'-',waaupo) ='408217-0' and oaagnr =10 then 1
      when concat(waaunr,'-',waaupo) ='408218-0' and oaagnr =10 then 0
  end,
  plan_date = case
      when concat(waaunr,'-',waaupo) ='408216-0' and oaagnr =10 then '2019-07-05'
      when concat(waaunr,'-',waaupo) ='408217-0' and oaagnr =10 then '2019-07-05'
      when concat(waaunr,'-',waaupo) ='408218-0' and oaagnr =10 then '2019-07-06'
  end
where concat(waaunr,'-',waaupo) in ('408216-0', '408217-0', '408218-0')
Aber leider habe ich das Problem, dass ich die Fehlermeldung "Column 'sequence' cannot be null" bekomme.

Wenn ich das richtig sehe, wird der Wert für die Spalten nicht erkannt.

Sieht jemand was ich falsch mache und kann mir jemand einen Tip geben?

Vielen Dank
Patrick

So wie ich das sehe ist die where-Klausel nicht richtig konstruiert. oaagnr ist doch für alle Zeilen, die upgedated werden sollen, gleich (10 im obigen Beispiel), oder. Daher gehört diese Bedingung in die where-Klausel, nicht in die when-Klauseln für das Case statement. Mit deinem obigen Konstrukt findet die Query auch Zeilen, die zwar die gewünschte waaaunr und waaupo-Werte haben, aber andere oaagnr-Werte. Die werden upgedatet, nur halt mit NULL da keines der when-Klauseln auf die Zeile Matcht.

Delphi-Quellcode:
update as400 set
  sequence = case
      when concat(waaunr,'-',waaupo) ='408216-0' then 1
      when concat(waaunr,'-',waaupo) ='408217-0' then 2
      when concat(waaunr,'-',waaupo) ='408218-0' then 3
  end,
  frozen = case
      when concat(waaunr,'-',waaupo) ='408216-0' then 1
      when concat(waaunr,'-',waaupo) ='408217-0' then 1
      when concat(waaunr,'-',waaupo) ='408218-0' then 0
  end,
  plan_date = case
      when concat(waaunr,'-',waaupo) ='408216-0' then '2019-07-05'
      when concat(waaunr,'-',waaupo) ='408217-0' then '2019-07-05'
      when concat(waaunr,'-',waaupo) ='408218-0' then '2019-07-06'
  end
where concat(waaunr,'-',waaupo) in ('408216-0', '408217-0', '408218-0')
  and (oaagnr =10)
Wer auf diese Spaltennamen gekommen ist gehört übrigens standrechtlich erschossen. :wink:

Delphi.Narium 6. Jul 2019 12:04

AW: Mehrfach Update Statement
 
Zitat:

Zitat von peterbelow (Beitrag 1436154)
So wie ich das sehe ist die where-Klausel nicht richtig konstruiert. oaagnr ist doch für alle Zeilen, die upgedated werden sollen, gleich (10 im obigen Beispiel), oder. Daher gehört diese Bedingung in die where-Klausel, nicht in die when-Klauseln für das Case statement. Mit deinem obigen Konstrukt findet die Query auch Zeilen, die zwar die gewünschte waaaunr und waaupo-Werte haben, aber andere oaagnr-Werte. Die werden upgedatet, nur halt mit NULL da keines der when-Klauseln auf die Zeile Matcht.

Delphi-Quellcode:
update as400 set
  sequence = case
      when concat(waaunr,'-',waaupo) ='408216-0' then 1
      when concat(waaunr,'-',waaupo) ='408217-0' then 2
      when concat(waaunr,'-',waaupo) ='408218-0' then 3
  end,
  frozen = case
      when concat(waaunr,'-',waaupo) ='408216-0' then 1
      when concat(waaunr,'-',waaupo) ='408217-0' then 1
      when concat(waaunr,'-',waaupo) ='408218-0' then 0
  end,
  plan_date = case
      when concat(waaunr,'-',waaupo) ='408216-0' then '2019-07-05'
      when concat(waaunr,'-',waaupo) ='408217-0' then '2019-07-05'
      when concat(waaunr,'-',waaupo) ='408218-0' then '2019-07-06'
  end
where concat(waaunr,'-',waaupo) in ('408216-0', '408217-0', '408218-0')
  and (oaagnr =10)
Wer auf diese Spaltennamen gekommen ist gehört übrigens standrechtlich erschossen. :wink:

Erscheint mir noch zu kompliziert.
Falls waaunr Integer, dann Hochkommas weg!!!
SQL-Code:
update as400 set
  sequence = case
      when waaunr = '408216' then 1
      when waaunr = '408217' then 2
      when waaunr = '408218' then 3
  end,
  frozen = case
      when waaunr = '408216' then 1
      when waaunr = '408217' then 1
      when waaunr = '408218' then 0
  end,
  plan_date = case
      when waaunr = '408216' then '2019-07-05'
      when waaunr = '408217' then '2019-07-05'
      when waaunr = '408218' then '2019-07-06'
  end
where waaunr in ('408216', '408217', '408218')
  and waaupo = 0
  and oaagnr = 10
Concats in Wherebedingungen machen das nur langsamer, da kaum ein Index genutzt werden kann. Mag bei kleinen Datenmengen ok sein, aber allgemein lieber eher nicht.

Und so, wie man in 'ner Wherebedingung mehrere Vergleiche per And oder per Or verknüpfen kann, kann man das auch im When. Sind mehrere Spalten bei einem When zu vergleichen, dann ist der Vergleich als Zeichenfolge via Concat eher die schlechtere Alternative.

Ykcim 8. Jul 2019 08:15

AW: Mehrfach Update STatement
 
Hallo Zusammen,

oaagnr kann unterschiedlich sein. In diesem aktuellen Beispiel ist es zwar identisch, aber bei nachfolgenden Prozessen ist das nicht sichergestellt. Daher muss ich es als zusätzlichen Parameter verwenden. Und auch waaupo ist zwar meistens 0 aber nicht immer...

Und wenn es unterschiedlich ist, kenne ich nicht die Syntax, es anders unterzubringen...

Gruß
Patrick

hoika 8. Jul 2019 08:23

AW: Mehrfach Update STatement
 
Hallo,
WaitCursor und gut is ;)

PS:
Eine Stored Procedure könnte das ev. noch beschleunigen.

Delphi.Narium 8. Jul 2019 09:01

AW: Mehrfach Update STatement
 
SQL-Code:
update as400 set
  sequence = case
      when waaunr = '408216' and waaupo = 0 and oaagnr = 10 then 1
      when waaunr = '408217' and waaupo = 0 and oaagnr = 10 then 2
      when waaunr = '408218' and waaupo = 0 and oaagnr = 10 then 3
      else sequence
  end,
  frozen = case
      when waaunr = '408216' and waaupo = 0 and oaagnr = 10 then 1
      when waaunr = '408217' and waaupo = 0 and oaagnr = 10 then 1
      when waaunr = '408218' and waaupo = 0 and oaagnr = 10 then 0
      else frozen
  end,
  plan_date = case
      when waaunr = '408216' and waaupo = 0 and oaagnr = 10 then '2019-07-05'
      when waaunr = '408217' and waaupo = 0 and oaagnr = 10 then '2019-07-05'
      when waaunr = '408218' and waaupo = 0 and oaagnr = 10 then '2019-07-06'
      else plan_date
  end
where waaunr in ('408216', '408217', '408218')
Geht es damit?

Würde aber ggfls. eine kaum überschaubare Menge von Datensätzen verändern, die nicht verändert werden muss.

Aber eigentlich:

Wenn oaagnr unterschiedlich sein kann, dann muss das Update halt eben für jeden der möglichen Werte gemacht werden. Dann reicht halt eben ein "globalgalaktisches" Update für "alles in einem Rutsch" nicht aus.

Und wenn waaupo nicht immer gleich ist, dann muss eben für jede zulässige Kombination aus waaupo, oaagnr und waaunr ein Update gemacht werden.

SQL ist übrigens bei kleinen Datenmengen deutlich schneller, als bei "einmal grob so alles mögliche und dann mal schaun, ob's eventuell doch nicht passt" ;-)
Die Ausführung vieler Updates mit exakten Angaben zu waaupo, oaagnr und waaunr kann daher deutlich schneller sein, als die momentan favorisierte Variante und: Das gerade aktut auftretende Problem muss nicht irgendwie umschifft werden sondern tritt garnicht erst auf und vermeidet ggfls. fälschlich durchgeführte Updates auf Datensätze, die nicht geändert werden müssen. Was z. B. bei meinem obigen Updatestatement der Fall ist. Gibt es da auf der Datenbank irgendwelche Trigger, so werden diese auch ausgeführt, was durchaus kontraproduktiv sein kann, wenn sie z. B. eine Versionierung ... durchführen.

Im konkreten Fall erwarte ich eigentlich dashier:
SQL-Code:
update as400 set sequence = 1, frozen = 1, plan_date = '2019-07-05' where waaunr = '408216' and waaupo = 0 and oaagnr = 10;

update as400 set sequence = 2, frozen = 1, plan_date = '2019-07-05' where waaunr = '408217' and waaupo = 0 and oaagnr = 10;

update as400 set sequence = 3, frozen = 0, plan_date = '2019-07-06' where waaunr = '408218' and waaupo = 0 and oaagnr = 10;
Man kann SQL-Statements wunderbar parametrisieren:
SQL-Code:
update as400 set sequence = :sequence, frozen = :frozen, plan_date = :plan_date
where waaunr = :waaunr and waaupo = :waaupo and oaagnr = :oaagnr;
und hat damit im Quelltext nur noch ein kurzes und verständliches Updatestatement.

Das ruft man dann für jede erforderliche Wertekombination auf, wobei das im Quelltext vermutlich deutlich einfacher umzusetzen ist, als der Zusammenbau des momentan genutzten Statements.

jobo 8. Jul 2019 09:18

AW: Mehrfach Update STatement
 
@Delphi.Narium :thumb:

Damit's nicht ganz so übersichtlich wird, wie Delphi.Narium es vorschlägt noch eine Ergänzung/Frage:
Woher kommen die neuen Daten?
Werden sie eingetippt? Oder "ergeben" sie sich aus anderen, bereits vorhandenen Daten, die mglw. sogar in einer Schleife abgerufen werden, in der dann das Updatestatement gebaut und gestartet wird?

Wenn das der Fall ist, kann man vielleicht auch alle Updateparameter und Join Kriterien auch über ein Select holen und an das Update übergeben.
Stichwort: korreliertes Update
Damit hätte man dann (wieder) ein Massenupdate, das aber seine Quelldaten aus der DB bekommt, also komplett auf der DB abläuft und auch sehr schnell ist.

Schokohase 8. Jul 2019 09:22

AW: Mehrfach Update STatement
 
Zitat:

Zitat von Delphi.Narium (Beitrag 1436260)
Man kann SQL-Statements wunderbar parametrisieren:
SQL-Code:
update as400 set sequence = :sequence, frozen = :frozen, plan_date = :plan_date
where waaunr = :waaunr and waaupo = :waaupo and oaagnr = :oaagnr;
und hat damit im Quelltext nur noch ein kurzes und verständliches Updatestatement.

Das ruft man dann für jede erforderliche Wertekombination auf, wobei das im Quelltext vermutlich deutlich einfacher umzusetzen ist, als der Zusammenbau des momentan genutzten Statements.

Und wenn man die Parameter in einem/r Record/Klasse zusammenfasst und einer Methode eine Auflistung davon übergibt, dann wird das alles zum Spaziergang.

Transaktion starten, jedes Item durch das Update-Statement jagen (Parameter setzen und ausführen) und Transaktion comitten.

Ykcim 8. Jul 2019 11:08

AW: Mehrfach Update STatement
 
Also die Daten ergeben sich. Der User schiebt per Drag&Drop die Zeilen einer Tabelle, um eine gute Auftragsreihenfolge zu erhalten. Aus der Position des Auftrags werden die Werte errechnet. Sequence zeigt die Reichenfolge an.
Ich erstelle mir das Update-Query in einer Functionanhand der Daten in der Tabelle. Die Daten können von Menge und Inhalt sehr unterschiedlich sein.
Delphi-Quellcode:
function TMySQLDB.Planung_Speichern(SG: TAdvStringGrid): boolean;
var  I: integer;
      where_SQL: string;
begin
   FMyWriteQuery.SQL.Clear;
   FMyWriteQuery.SQL.Add('update as400 set ');
   //Sequence
   FMyWriteQuery.SQL.Add('sequence = case ');
   where_SQL:=' where concat(waaunr,'+QuotedStr('-')+',waaupo,'+QuotedStr('-')+',oaagnr) in (';
   for I := 2 to SG.RowCount -2 do begin      //Filter-Zeile und FloatingFooter
      FMyWriteQuery.SQL.Add(' when concat(waaunr,'+QuotedStr('-')+',waaupo) ='+QuotedStr(SG.Cells[1,I])+
                            ' and oaagnr ='+SG.Cells[5,I]+' then '+SG.Cells[0,I]+' ');
      if I=2 then
         where_SQL:=where_SQL+QuotedStr(SG.Cells[1,I]+'-'+SG.Cells[5,I])
      else
         where_SQL:=where_SQL+', '+QuotedStr(SG.Cells[1,I]+'-'+SG.Cells[5,I]);
   end;
   FMyWriteQuery.SQL.Add(' else 0 end, ');

   //Frozen
   FMyWriteQuery.SQL.Add('frozen = case ');
   for I := 2 to SG.RowCount -2 do begin      //Filter-Zeile und FloatingFooter
      FMyWriteQuery.SQL.Add(' when concat(waaunr,'+QuotedStr('-')+',waaupo) ='+QuotedStr(SG.Cells[1,I])+
                            ' and oaagnr ='+SG.Cells[5,I]+' then '+SG.Cells[25,I]+' ');
   end;
   FMyWriteQuery.SQL.Add(' else 0 end, ');

   //PlanDate
   FMyWriteQuery.SQL.Add('plan_date = case ');
   for I := 2 to SG.RowCount -2 do begin      //Filter-Zeile und FloatingFooter
      FMyWriteQuery.SQL.Add(' when concat(waaunr,'+QuotedStr('-')+',waaupo) ='+QuotedStr(SG.Cells[1,I])+
                            ' and oaagnr ='+SG.Cells[5,I]+' then '+QuotedStr(copy(SG.Cells[14,I],7,4)+'-'+copy(SG.Cells[14,I],4,2)+'-'+copy(SG.Cells[14,I],1,2))+' ');
   end;
   FMyWriteQuery.SQL.Add(' else '+QuotedStr('0000-00-00')+' end ');

   where_SQL:=where_SQL+')';
   FMyWriteQuery.SQL.Add(where_SQL);

   FMyWriteQuery.Execute;
   Result:=true;
end;
Ich habe vorher Einzelupdates gehabt und hatte das Problem, dass das sehr lange dauerte (mehrere Sekunden, obwohl ich nur die ersten 15 Zeile gespeichert habe). Jetzt geht es sehr schnell, sodass ich problemlos mehrere Tabelle auf einmal speichern kann.

Daher bin ich mit dieser Lösung gerade sehr glücklich...
Delphi-Quellcode:
update as400 set
  sequence = case
      when (concat(waaunr,'-',waaupo) ='408216-0' and oaagnr =10) then 1
      when (concat(waaunr,'-',waaupo) ='408217-0' and oaagnr =10) then 2
      when (concat(waaunr,'-',waaupo) ='408218-0' and oaagnr =10) then 3
      else 0
  end,
  frozen = case
      when (concat(waaunr,'-',waaupo) ='408216-0' and oaagnr =10) then 1
      when (concat(waaunr,'-',waaupo) ='408217-0' and oaagnr =10) then 1
      when (concat(waaunr,'-',waaupo) ='408218-0' and oaagnr =10) then 0
      else 0
  end,
  plan_date = case
      when (concat(waaunr,'-',waaupo) ='408216-0' and oaagnr =10) then '2019-07-05'
      when (concat(waaunr,'-',waaupo) ='408217-0' and oaagnr =10) then '2019-07-05'
      when (concat(waaunr,'-',waaupo) ='408218-0' and oaagnr =10) then '2019-07-06'
      else '000-00-00'
  end
where concat(waaunr,'-',waaupo,'-',oaagnr) in ('408216-0-10', '408217-0-10', '408218-0-10')
Zitat:

Wer auf diese Spaltennamen gekommen ist gehört übrigens standrechtlich erschossen.
Spaltenname von XPPS... ;-)

Gruß Patrick

peterbelow 8. Jul 2019 11:29

AW: Mehrfach Update STatement
 
Zitat:

Zitat von Ykcim (Beitrag 1436252)
Hallo Zusammen,

oaagnr kann unterschiedlich sein. In diesem aktuellen Beispiel ist es zwar identisch, aber bei nachfolgenden Prozessen ist das nicht sichergestellt. Daher muss ich es als zusätzlichen Parameter verwenden. Und auch waaupo ist zwar meistens 0 aber nicht immer...

Und wenn es unterschiedlich ist, kenne ich nicht die Syntax, es anders unterzubringen...

Gruß
Patrick

Naja, aber Du mußt sicherstellen, dass die WHERE-Klausel wirklich nur die Zeilen findet, die Du updaten willst, sonst hast Du halt das Problem, dass für manche der gefundenen Zeilen keine der When-Klauseln passt und dann halt NULL in die Spalte geschrieben wird.

Mmh, doch, Du könntest für jedes Case eine ELSE-Klausel verwenden, die einfach den aktuellen Wert der Spalte in diese schreibt.

Code:
update as400 set
  sequence = case
      when (concat(waaunr,'-',waaupo) ='408216-0' and oaagnr =10) then 1
      when (concat(waaunr,'-',waaupo) ='408217-0' and oaagnr =10) then 2
      when (concat(waaunr,'-',waaupo) ='408218-0' and oaagnr =10) then 3
      else sequence
  end,
  frozen = case
      when (concat(waaunr,'-',waaupo) ='408216-0' and oaagnr =10) then 1
      when (concat(waaunr,'-',waaupo) ='408217-0' and oaagnr =10) then 1
      when (concat(waaunr,'-',waaupo) ='408218-0' and oaagnr =10) then 0
      else frozen
  end,
  plan_date = case
      when (concat(waaunr,'-',waaupo) ='408216-0' and oaagnr =10) then '2019-07-05'
      when (concat(waaunr,'-',waaupo) ='408217-0' and oaagnr =10) then '2019-07-05'
      when (concat(waaunr,'-',waaupo) ='408218-0' and oaagnr =10) then '2019-07-06'
      else plan_date
  end
where concat(waaunr,'-',waaupo,'-',oaagnr) in ('408216-0-10', '408217-0-10', '408218-0-10')
Probier mal aus, ob die Datenbank-Engine sowas akzeptiert.

Ykcim 8. Jul 2019 12:04

AW: Mehrfach Update STatement
 
Zitat:

Naja, aber Du mußt sicherstellen, dass die WHERE-Klausel wirklich nur die Zeilen findet, die Du updaten willst, sonst hast Du halt das Problem, dass für manche der gefundenen Zeilen keine der When-Klauseln passt und dann halt NULL in die Spalte geschrieben wird.
Das stelle ich dadurch sicher, dass waaunr, waaupo und oaagnr als Kombination unique sind und als Primärschlüssel fungieren... Daher behaupte ich, dass mit meinem aktuellen Statement wirklich nur die Zeile upgedatet werden, die auch einen Wert haben. Das ELSE nutze ich nur, weil es sonst einen Fehler in der Syntax gibt...

Gruß Patrick

Delphi.Narium 8. Jul 2019 12:25

AW: Mehrfach Update STatement
 
Case when funktioniert auch ohne Else und zwar ohne Syntaxfehler. Welchen Syntaxfehler erhältst Du denn?

Was mir schleierhaft ist:
SQL-Code:
update as400 set
  sequence = case
      when (concat(waaunr,'-',waaupo) ='408216-0' and oaagnr =10) then 1
      when (concat(waaunr,'-',waaupo) ='408217-0' and oaagnr =10) then 2
      when (concat(waaunr,'-',waaupo) ='408218-0' and oaagnr =10) then 3
      else 0
  end,
  frozen = case
      when (concat(waaunr,'-',waaupo) ='408216-0' and oaagnr =10) then 1
      when (concat(waaunr,'-',waaupo) ='408217-0' and oaagnr =10) then 1
      when (concat(waaunr,'-',waaupo) ='408218-0' and oaagnr =10) then 0
      else 0
  end,
  plan_date = case
      when (concat(waaunr,'-',waaupo) ='408216-0' and oaagnr =10) then '2019-07-05'
      when (concat(waaunr,'-',waaupo) ='408217-0' and oaagnr =10) then '2019-07-05'
      when (concat(waaunr,'-',waaupo) ='408218-0' and oaagnr =10) then '2019-07-06'
      else '000-00-00'
  end
where concat(waaunr,'-',waaupo,'-',oaagnr) in ('408216-0-10', '408217-0-10', '408218-0-10')
Im where setzt du 3 Werte per Concat zusammen, im When zwei und den dritten fügst Du per and hinzu.

Warum, wo ist da der sittliche Nährwert? Es sind doch letztlich die gleichen Wertkombinationen abzufragen.

So wäre es dann schon etwas konsequenter:
SQL-Code:
update as400 set
  sequence = case
      when (concat(waaunr,'-',waaupo,'-',oaagnr) = '408216-0-10') then 1
      when (concat(waaunr,'-',waaupo,'-',oaagnr) = '408217-0-10') then 2
      when (concat(waaunr,'-',waaupo,'-',oaagnr) = '408218-0-10') then 3
      else 0
  end,
  frozen = case
      when (concat(waaunr,'-',waaupo,'-',oaagnr) = '408216-0-10') then 1
      when (concat(waaunr,'-',waaupo,'-',oaagnr) = '408217-0-10') then 1
      when (concat(waaunr,'-',waaupo,'-',oaagnr) = '408218-0-10') then 0
      else 0
  end,
  plan_date = case
      when (concat(waaunr,'-',waaupo,'-',oaagnr) ='408216-0-10') then '2019-07-05'
      when (concat(waaunr,'-',waaupo,'-',oaagnr) ='408217-0-10') then '2019-07-05'
      when (concat(waaunr,'-',waaupo,'-',oaagnr) ='408218-0-10') then '2019-07-06'
      else '000-00-00'
  end
where concat(waaunr,'-',waaupo,'-',oaagnr) in ('408216-0-10', '408217-0-10', '408218-0-10')
Oder auch so:
SQL-Code:
update as400 set
  sequence = case
      when waaunr = '408216' and waaupo = 0 and oaagnr = 10 then 1
      when waaunr = '408217' and waaupo = 0 and oaagnr = 10 then 2
      when waaunr = '408218' and waaupo = 0 and oaagnr = 10 then 3
      else 0
  end,
  frozen = case
      when waaunr = '408216' and waaupo = 0 and oaagnr = 10 then 1
      when waaunr = '408217' and waaupo = 0 and oaagnr = 10 then 1
      when waaunr = '408218' and waaupo = 0 and oaagnr = 10 then 0
      else 0
  end,
  plan_date = case
      when waaunr = '408216' and waaupo = 0 and oaagnr = 10 then '2019-07-05'
      when waaunr = '408217' and waaupo = 0 and oaagnr = 10 then '2019-07-05'
      when waaunr = '408217' and waaupo = 0 and oaagnr = 10 then '2019-07-06'
      else '0000-00-00'
  end
where waaunr in ('408216', '408217', '408218') and waaupo = 0 and oaagnr = 10
Die von Dir bisher gewählte Variante hätte ich früher höchstwahrscheinlich nicht durch den Test und die Qualitätssicherung bekommen, da bei ihr potenziell Datensätze geändert werden könnten, die nicht geändert werden dürfen. Und genau diese Fehlermöglichkeit war ja überhaupt erst der Grund, weshalb Du diesen Thread eröffnet hast.

Ykcim 8. Jul 2019 12:40

AW: Mehrfach Update STatement
 
Also die erste Lösung würde funktionieren, aber die Möglichkeit der 3 Werte mit concat zusammen zu fassen hatte ich erst später. Aber das könnte ich ändern.
Deine zweite Lösung funktioniert nicht, da die Kombination AuftragsNr (waaunr) dem Zusatz (waaupo) und der ArbeitsgangNr (oaagnr) bei jedem Auftrag eine andere sein kann. Je nachdem bei welchem AG man gerade ist und es ist möglich, dass Aufträge mit einer unterschiedlichen ArbeitsgangNr auf der selben Maschine laufen und dann beim Speichern in der selben Tabelle stehen...

Die Variante die ich aktuell nutze schließt es meines Erachtens aus, dass Datensätze geändert werden, die nicht geändert werden sollen.

Zitat:

Case when funktioniert auch ohne Else und zwar ohne Syntaxfehler. Welchen Syntaxfehler erhältst Du denn?
Ich werde das Thema ohne ELS noch einemal testen. Ich denke, dass die Tatsache, dass ungewollt andere Datensätze geändert wurden, für die kein Wert in der Where-Klausel vorhanden waren, zu dem Fehler führten. In der letzten Where-Klausel hatte ich ja waaunr und waaupo abgefragt. Die Kombination ist ja für alle Arbeitsgänge des Auftrags dieselbe. Nur wenn man die ArbeitsgangNr (oaagnr) auch noch abfragt, ist eine Eindeutigkeit garantiert... Daher habe ich oaagnr mit in das concat eingebunden...

Gruß
Patrick

p80286 8. Jul 2019 23:09

AW: Mehrfach Update STatement
 
Zitat:

Zitat von Delphi.Narium (Beitrag 1436287)
Die von Dir bisher gewählte Variante hätte ich früher höchstwahrscheinlich nicht durch den Test und die Qualitätssicherung bekommen, da bei ihr potenziell Datensätze geändert werden könnten, die nicht geändert werden dürfen. Und genau diese Fehlermöglichkeit war ja überhaupt erst der Grund, weshalb Du diesen Thread eröffnet hast.

:thumb:
Wobei ich vom Verständnis her mit
Code:
 else 0
ein Problem habe. Ich würde ein
SQL-Code:
else Sequence
....
else frozen
....
else plan_date
bevorzugen, falls das syntaktisch möglich ist, oder noch besser, im else-Zweig gar nichts tun.

Gruß
K-H

peterbelow 9. Jul 2019 03:35

AW: Mehrfach Update STatement
 
[QUOTE=p80286;1436333]
Zitat:

Zitat von Delphi.Narium (Beitrag 1436287)

... falls das syntaktisch möglich ist, oder noch besser, im else-Zweig gar nichts tun.

Gruß
K-H

"gar nichts tun" ist halt nicht. Wenn keine der when-Klauseln zutrifft ist das Resultat des Case-Statements NULL.

Delphi.Narium 9. Jul 2019 07:42

AW: Mehrfach Update STatement
 
[QUOTE=peterbelow;1436335]
Zitat:

Zitat von p80286 (Beitrag 1436333)
Zitat:

Zitat von Delphi.Narium (Beitrag 1436287)

... falls das syntaktisch möglich ist, oder noch besser, im else-Zweig gar nichts tun.

Gruß
K-H

"gar nichts tun" ist halt nicht. Wenn keine der when-Klauseln zutrifft ist das Resultat des Case-Statements NULL.

und damit sind wir dann wieder bei der Ausgangsfehlermeldung ;-)

@p80286

Verständnisproblem bei
SQL-Code:
else 0
?

Naja, sagen wir mal so: Für meine Begriffe ist das schlichtweg falsch. Eigentlich hab' ich dafür nur Unverständnis übrig ;-)


Alle Zeitangaben in WEZ +1. Es ist jetzt 14:16 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