AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Mehrfach Update STatement

Ein Thema von Ykcim · begonnen am 5. Jul 2019 · letzter Beitrag vom 9. Jul 2019
Antwort Antwort
Delphi.Narium

Registriert seit: 27. Nov 2017
2.434 Beiträge
 
Delphi 7 Professional
 
#1

AW: Mehrfach Update STatement

  Alt 8. Jul 2019, 09:01
SQL-Code:
update as400 set
  sequence = case
      when waaunr = '408216and waaupo = 0 and oaagnr = 10 then 1
      when waaunr = '408217and waaupo = 0 and oaagnr = 10 then 2
      when waaunr = '408218and waaupo = 0 and oaagnr = 10 then 3
      else sequence
  end,
  frozen = case
      when waaunr = '408216and waaupo = 0 and oaagnr = 10 then 1
      when waaunr = '408217and waaupo = 0 and oaagnr = 10 then 1
      when waaunr = '408218and waaupo = 0 and oaagnr = 10 then 0
      else frozen
  end,
  plan_date = case
      when waaunr = '408216and waaupo = 0 and oaagnr = 10 then '2019-07-05'
      when waaunr = '408217and waaupo = 0 and oaagnr = 10 then '2019-07-05'
      when waaunr = '408218and 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-05where waaunr = '408216and waaupo = 0 and oaagnr = 10;

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

update as400 set sequence = 3, frozen = 0, plan_date = '2019-07-06where waaunr = '408218and 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.

Geändert von Delphi.Narium ( 8. Jul 2019 um 11:48 Uhr) Grund: Syntaxfehler im 1. SQL behoben
  Mit Zitat antworten Zitat
jobo

Registriert seit: 29. Nov 2010
3.072 Beiträge
 
Delphi 2010 Enterprise
 
#2

AW: Mehrfach Update STatement

  Alt 8. Jul 2019, 09:18
@Delphi.Narium

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.
Gruß, Jo
  Mit Zitat antworten Zitat
Schokohase
(Gast)

n/a Beiträge
 
#3

AW: Mehrfach Update STatement

  Alt 8. Jul 2019, 09:22
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.
  Mit Zitat antworten Zitat
Ykcim

Registriert seit: 29. Dez 2006
Ort: NRW
804 Beiträge
 
Delphi 10.4 Sydney
 
#4

AW: Mehrfach Update STatement

  Alt 8. Jul 2019, 11:08
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-0and oaagnr =10) then 1
      when (concat(waaunr,'-',waaupo) ='408217-0and oaagnr =10) then 2
      when (concat(waaunr,'-',waaupo) ='408218-0and oaagnr =10) then 3
      else 0
  end,
  frozen = case
      when (concat(waaunr,'-',waaupo) ='408216-0and oaagnr =10) then 1
      when (concat(waaunr,'-',waaupo) ='408217-0and oaagnr =10) then 1
      when (concat(waaunr,'-',waaupo) ='408218-0and oaagnr =10) then 0
      else 0
  end,
  plan_date = case
      when (concat(waaunr,'-',waaupo) ='408216-0and oaagnr =10) then '2019-07-05'
      when (concat(waaunr,'-',waaupo) ='408217-0and oaagnr =10) then '2019-07-05'
      when (concat(waaunr,'-',waaupo) ='408218-0and 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
Patrick
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 20:04 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