DBTab Update from Table oder in Loop mit "Update Set" Oder ?

Die Frage ist als "gelöst" markiert. Den entsprechend Beitrag findest du hier.

Alles rund um die Sprache ABAP®: Funktionsbausteine, Listen, ALV
10 Beiträge • Seite 1 von 1
10 Beiträge Seite 1 von 1

DBTab Update from Table oder in Loop mit "Update Set" Oder ?

Beitrag von RIG (Specialist / 110 / 30 / 1 ) »
Hallo liebes Forum,

trotz einiger Suche habe ich leider noch keine befriedigende Antwort für eine Fragestellung gefunden.

Folgendes Szenario:

DBTAB_A hat 150 Felder und 1 KeyFeld

Ich möchte nun 2 Werte, nennen wir Sie Feld120 und Feld121, pro Eintrag in der DB updaten, leider keine Konstanten Werte sonst würde "Update Set" gut funktionieren.

Gibt es eine bessere Lösung als Update dbtab_a from table itab?

mit besser meine ich:

von der DBTAB_A benötige ich im Programmverlauf nur eine Handvoll Felder, weshalb ich nur ungern die ganze Tabelle selektieren möchte.
Auch beim Update braucht die DB ja nicht jedes Feld vergleichen und ggf. Updaten sondern nur meine 2 Felder (Feld120 & Feld121) mit dem Schlüssel prüfen.

Ein Update from Table mit einer kurzen Tabelle aus Key + Updatefeldern ist mir nicht bekannt - deshalb nun meine Frage:

- besser Update from Table
- oder besser Update Set in einem Loop?
- oder eine Möglichkeit die ich noch übersehe und besser als die beiden genannten ist.

Ich bin gespannt auf eure Antworten.

gesponsert
Stellenangebote auf ABAPforum.com schalten
kostenfrei für Ausbildungsberufe und Werksstudenten


Re: DBTab Update from Table oder in Loop mit "Update Set" Od

Beitrag von lausek (ForumUser / 64 / 2 / 20 ) »
Mit "keine konstanten Werte" meinst du dass sich die Spalten ändern können, oder?

Ein bisschen Code würde vielleicht helfen, die Problematik etwas klarer zu machen. Btw, welche Release Version hast du?

Re: DBTab Update from Table oder in Loop mit "Update Set" Od

Beitrag von DeathAndPain (Top Expert / 1941 / 257 / 412 ) »
Ich verstehe ihn so, dass er bei allen Zeilen zwei Spalten updaten möchte, basierend auf Werten aus anderen Spalten derselben Zeile. Es sind aber dennoch nur wenige Spalten, die er da braucht.
von der DBTAB_A benötige ich im Programmverlauf nur eine Handvoll Felder, weshalb ich nur ungern die ganze Tabelle selektieren möchte.
Was meinst Du mit "Handvoll Felder"? Meinst Du a) "Handvoll Spalten" oder meinst Du b), dass Du nur wenige Zeilen bearbeiten willst?

Wenn a): Mach keinen SELECT *, sondern führe die Spalten, die Du brauchst, explizit auf. Das ist sowieso ordentlicher Programmierstil.

Wenn b): Selektiere halt die Zeilen, die Du brauchst, in eine interne Tabelle. Wenn Du nicht über den Primärschlüssel selektieren solltest, kannst Du ggf. darüber nachdenken, einen zusätzlichen Datenbankindex auf der Datenbanktabelle anzulegen, der zu Deinem Zugriff passt. (Muss natürlich von der Nutzungshäufigkeit her gerechtfertigt sein.)

Letztlich läuft es auf einen LOOP hinaus, bei dem Du die interne Tabelle mit den selektierten Spalten durchhechelst und die zu verändernden Spalten berechnest. Ob Du dann einen UPDATE FROM TABLE oder einen UPDATE SET nimmst, müsste man antesten. UPDATE FROM TABLE wird vermutlich schneller sein, aber in seiner herkömmlichen Form erfordert er, dass Du vorher doch per SELECT * die ganzen anderen Spalten einliest.

Re: DBTab Update from Table oder in Loop mit "Update Set" Od

Beitrag von RIG (Specialist / 110 / 30 / 1 ) »
lausek hat geschrieben:Mit "keine konstanten Werte" meinst du dass sich die Spalten ändern können, oder?

Ein bisschen Code würde vielleicht helfen, die Problematik etwas klarer zu machen.

Hallo und Danke für die Antworten.
DeathAndPain hat es richtig interpretiert, meine Anforderung als Coding wären:

Code: Alles auswählen.

DATA: gt_ztable_150 type STANDARD TABLE OF ztable150. "Tabelle mit ca 150 Spalten

*Variante 1

Select * from ztable into TABLE gt_ztable_150 where field in so_fieldoption.  "gehen wir mal von 1000 Zeilen aus
  
Perform ein_großes_wunder.    "hier werden jetzt die u.a. die Felder 120 & 121 (Feld / Spalte) 
                              "mit verschiedensten Werten gefüllt (kaum Zeilen gleich)
Perform db_locks.
  
UPDATE ztable150 from gt_ztable_150.

**************************************************************************************************************  
  
*Variante 2
Select Feld_1 Feld_10 Feld_11 Feld_12 Feld_13 Feld_14 Feld_15 Feld_120 Feld_121 
  from ztable150 into TABLE gt_ztable_150_short.  "gt_ztable_150_short könnte ein angepasster Datentyp sein
 
Perform ein_großes_wunder.    "hier werden jetzt die u.a. die Felder 120 & 121 (Feld / Spalte) 
                              "mit verschiedensten Werten gefüllt (kaum Zeilen gleich)
Perform db_locks.
  
LOOP AT gt_ztable_150_short ASSIGNING <fs>.
  UPDATE ztable150 set Feld_120 = <fs>-feld_120
                       Feld_121 = <fs>-feld_121
                       where Feld_1 eq <fs>-feld_1.
ENDLOOP.
DeathAndPain hat geschrieben: Wenn a): Mach keinen SELECT *, sondern führe die Spalten, die Du brauchst, explizit auf. Das ist sowieso ordentlicher Programmierstil.

Wenn b): Selektiere halt die Zeilen, die Du brauchst, in eine interne Tabelle. Wenn Du nicht über den Primärschlüssel selektieren solltest, kannst Du ggf. darüber nachdenken, einen zusätzlichen Datenbankindex auf der Datenbanktabelle anzulegen, der zu Deinem Zugriff passt. (Muss natürlich von der Nutzungshäufigkeit her gerechtfertigt sein.)

Letztlich läuft es auf einen LOOP hinaus, bei dem Du die interne Tabelle mit den selektierten Spalten durchhechelst und die zu verändernden Spalten berechnest. Ob Du dann einen UPDATE FROM TABLE oder einen UPDATE SET nimmst, müsste man antesten. UPDATE FROM TABLE wird vermutlich schneller sein, aber in seiner herkömmlichen Form erfordert er, dass Du vorher doch per SELECT * die ganzen anderen Spalten einliest.
Eine Mischung aus a & b, in jedem Programmlauf werden zwischen 1000 und 30000 Zeilen selektiert, ich benötige für mein "großes Wunder" nicht all zu viele Spalten der Gesamtbreite, aber für ein Update from Table würde ich eben leider alle spalten benötigen. Der Zugriff auf die Einträge per Key/Index ist Gewährleistet.

Deswegen war meine Frage was besser ist oder ob es eventuell noch einen Charmanteren Weg gibt in dem ich nicht alles Selektieren muss und Trotzdem alles in einem Statement (einer DB-Anfrage) Updaten kann.

Ich habe mich zwischenzeitlich gefragt ob ich den Wald vor Bäumen nicht sehe, da ich aber diese Konstellation so noch nie hatte kam mir jetzt erst diese Fragestellung.
Normalerweise setzt man ja vlt nur Kennzeichen mit Set 'X' where [Bedingung die größere Treffermenge ergibt] - hier ist die Konstellation eben komplizierter und mir ging es darum ob man ein Weg bevorzugen sollte und wenn ja welchen.
lausek hat geschrieben: Btw, welche Release Version hast du?
SAP ECC 6.0

SAP_BASIS 700
SAP_ABA 700
SAP_AP 700
SAP_APPL 600
EA-APPL 600

Vielen Dank nochmal für euere Antworten.

Re: DBTab Update from Table oder in Loop mit "Update Set" Od

Beitrag von DeathAndPain (Top Expert / 1941 / 257 / 412 ) »
Bei dem alten Release wirst Du um die Wahl zwischen Pest (alles einlesen) und Cholera (zeilenweisen UPDATE SET) nicht herumkommen. Bei 7.50 hättest Du möglicherweise eine Chance gehabt, weil man da in der WHERE-Bedingung auch vergleichsweise komischen Kram angeben darf (möglicherweise wären da auch die von Dir benötigten Vergleiche innerhalb der Tabellenzeile zulässig). Alenfalls könntest Du prüfen, ob Du mit Native SQL was reißen kannst, indem Du mit einem entsprechenden Call das volle Feature Set Deiner Datenbank nutzt.

Auf der anderen Seite: Ich habe zwar auch emotionale Hemmungen, 30.000 Zeilen langer Tabellen zu puffern, aber man muss im Hinterkopf behalten, wie sich die Hauptspeichermengen in den letzten 15 Jahren weiterentwickelt haben. 2003 hatte ein PC vielleicht 512 MB RAM. Server hatten natürlich mehr, aber verglichen mit heutigen Verhältnissen war das auch lächerlich.

Wenn wir jetzt davon ausgehen, dass Deine Tabelle 20 Spalten vom Type CHAR100 hat, dann wäre das ja schon ziemlich opulent. Wenn wir dann noch annehmen, dass jedes Zeichen per Unicode mit 2 Byte codiert wird (was auch schon viel wäre), dann wären das pro Tabellenzeile 20 x 200 x 2 = 8000 Byte oder 8 kB. Davon 30.000 Zeilen macht 30.000 x 8 kB = 240.000 kB = 240 MB. Heutige Server haben Hauptspeicher in der Größenordnung vieler Gigabyte, teilweise liegen sie sogar im Terabytebereich (insbesondere die HANA-Teile). Für zwei Sekunden mal 240 MB zu belegen, um Ausführungszeit zu sparen, finde ich jetzt nicht verwerflich. Wichtig wäre dabei aber, nicht ein Ergebnis-ALV zu bringen, während Deine Hilfstabelle noch im Speicher steht, und der Anwender lässt das ALV dann auf dem Bildschirm stehen und macht erst mal eine halbe Stunde was anderes.

Entweder Deine Hilfstabelle ist eine lokale Tabelle innerhalb eines Unterprogramms, das den UPDATE organisiert - dann wird sie mit Verlassen des Unterprogramms wieder freigegeben (wenn Du nicht so dämlich bist, sie per STATICS zu deklarieren). Oder Du setzt nach Deinem UPDATE einen expliziten FREE-Befehl ab. Dann sollte das im grünen Bereich sein.

Re: DBTab Update from Table oder in Loop mit "Update Set" Od

Beitrag von RIG (Specialist / 110 / 30 / 1 ) »
Danke an alle für Eure Antworten,
ich tendiere auch zur Lösung des Select * und dann am ende Update from Table - zumal der Report im Hintergrund ausgeführt wird.

Im Dialogmodus hätte ich eventuell 2 Varianten programmiert und dann je nach Selektierter Datenmenge das Update Set im Loop oder eben Update from Table gewählt.
Aber so, habe ich jetzt keine Bauchschmerzen das nur als Update from Table zu implementieren.

Re: DBTab Update from Table oder in Loop mit "Update Set" Od

Beitrag von DeathAndPain (Top Expert / 1941 / 257 / 412 ) »
Im Dialogmodus hätte ich eventuell 2 Varianten programmiert und dann je nach Selektierter Datenmenge das Update Set im Loop oder eben Update from Table gewählt.
Wann hättest Du da was wählen wollen? Viele Daten = mehr Hauptspeicher, aber auch mehr laufzeitfressende UPDATE SET-Befehle. Wenn Du Deine Puffertabelle wieder freigibst, bevor Du den ALV anzeigst, dann gibt es technisch keinen relevanten Unterschied zwischen der Ausführung im Hintergrund und der im Dialogbetrieb.

Re: DBTab Update from Table oder in Loop mit "Update Set" Od

Beitrag von Daniel (Specialist / 314 / 68 / 44 ) »
Du könntest einen VIEW anlegen.
Den darfst du dann mit SELECT * einlesen
und mit UPDATE FROM TABLE fortschreiben.

Folgende Benutzer bedankten sich beim Autor Daniel für den Beitrag (Insgesamt 3):
black_adeptDeathAndPainRIG


Re: DBTab Update from Table oder in Loop mit "Update Set" Od

Beitrag von DeathAndPain (Top Expert / 1941 / 257 / 412 ) »
Und der lässt dann alle Spalten, die nicht in den View aufgenommen sind, unangetastet? Das wäre natürlich Klasse. Ich hätte vermutet, dass die dann auf initial gesetzt werden.

Re: DBTab Update from Table oder in Loop mit "Update Set" Od

Beitrag von Daniel (Specialist / 314 / 68 / 44 ) »
Was nicht im VIEW definiert ist wird nicht angefasst.

Seite 1 von 1

Vergleichbare Themen

3
Antw.
2981
Views
Update auf Datenbank
von SAP_ENTWICKLER » 22.09.2015 14:47 • Verfasst in ABAP® Core
2
Antw.
2667
Views
Update DB set expr
von Icke0801 » 18.02.2016 14:02 • Verfasst in ABAP® für Anfänger
2
Antw.
1727
Views
Update in Materialstammfeldern
von SAP_ENTWICKLER » 07.04.2016 14:57 • Verfasst in ABAP® Core
6
Antw.
4217
Views
Update DB-Tabelle
von L0w-RiDer » 02.10.2019 15:24 • Verfasst in ABAP® für Anfänger
0
Antw.
1141
Views
MM Konditionen Update
von basstoss » 30.11.2005 14:35 • Verfasst in ABAP® Core

Über diesen Beitrag


Die Frage ist als "gelöst" markiert. Den entsprechend Beitrag findest du hier.

Unterstütze die Community und teile den Beitrag für mehr Leser und Austausch

Newsletter Anmeldung

Keine Beiträge verpassen! Wöchentlich versenden wir lesenwerte Beiträge aus unserer Community.
Die letzte Ausgabe findest du hier.
Details zum Versandverfahren und zu Ihren Widerrufsmöglichkeiten findest du in unserer Datenschutzerklärung.

Unbeantwortete Forenbeiträge

Daten an Tabelle binden
vor 2 Tagen von Bright4.5 1 / 770
aRFC im OO-Kontext
vor 4 Wochen von ralf.wenzel 1 / 2392
Hilfe bei SWEC/SWE2
letzen Monat von retsch 1 / 8977