SAP_Tips - Kathe, Roland

Werbung
SAP_Tips
SAP_Tips
Table of Contents
1.
Performant programmieren................................................................................................................1
1.1
Vorwort....................................................................................................................................1
1.2
Open SQL................................................................................................................................1
1.3
Native SQL..............................................................................................................................3
2
Sammlung typischer (Performance−)Probleme und Lösungsvorschläge........................................4
2.1
Realisierung von Subqueries...................................................................................................4
2.2
Zugriffe auf logisch verknüpfte Tabellen................................................................................4
2.2.1
Geschachteltes SELECT.........................................................................................4
2.2.2
SELECT FOR ALL ENTRIES...............................................................................4
2.3
Portionsweises Einlesen..........................................................................................................6
2.4
Mengen Insert, Update, Delete................................................................................................6
2.4.1
Wie portionieren? Wann commit?..........................................................................6
2.4.2
Array−Update...........................................................................................................7
2.5
Existenzprüfung.......................................................................................................................7
2.6
ORDER BY versus ABAP Sort..............................................................................................7
2.7
DISTINCT versus ABAP SORT + DELETE ADJACENT DUPLICATES..........................8
2.8
Wann und wie Puffern?...........................................................................................................8
3
Tips & Tricks.........................................................................................................................................9
4
SQL Interface.......................................................................................................................................10
4.1
Projektion im Select..............................................................................................................10
4.2
Select ... Where vs. Select + Check.......................................................................................10
4.3
Select mit (Primär−)Index−Unterstützung............................................................................11
4.4
Select mit Buffer−Unterstützung..........................................................................................12
4.5
Select und Aggregatsfunktionen...........................................................................................13
4.6
Select mit ORDER BY vs. SORT.........................................................................................13
4.7
Existenzprüfung.....................................................................................................................14
4.8
Nutzung von Like/Between...................................................................................................15
4.9
Nutzung von RANGE/IN......................................................................................................16
4.10
Select single vs. Select−Endselect......................................................................................17
4.11
Select−Endselect vs. Array−Select.....................................................................................18
4.12
Select vs. Read....................................................................................................................19
4.13
Select und OR......................................................................................................................20
Select und OR........................................................................................................................................20
4.14
Select mit View...................................................................................................................21
4.15
Select mit View II...............................................................................................................21
4.16
Select mit FOR ALL ENTRIES..........................................................................................22
4.17
Select vs. OPEN CURSOR.................................................................................................23
4.18
Select vs. parallele CURSOR..............................................................................................25
4.19
Dynamischer vs. statischen SELECT..................................................................................26
4.20
Array−Insert vs. Einzelsatz−Insert......................................................................................27
4.21
Spalten−Update vs. klass. Update........................................................................................28
4.22
Select mit Unterabfrage (4.0)..............................................................................................28
4.23
Select mit INNER JOIN (4.0).............................................................................................30
4.24
Select mit LEFT OUTER JOIN (4.0)..................................................................................31
i
SAP_Tips
Table of Contents
5
Interne Tabellen...................................................................................................................................33
5.1
Interne Tabellen kopieren......................................................................................................33
5.2
Interne Tabellen vergleichen.................................................................................................34
5.3
Anhängen an eine Tabelle.....................................................................................................38
5.4
Aufbau von Tabellen ohne Dupletten...................................................................................39
5.5
Aufbau sortierter Tabellen....................................................................................................41
5.6
Aufbau von summierten Tabellen.........................................................................................43
5.7
Lineare Suche oder binary search..........................................................................................45
5.8
Versch. Arten von Schlüsselzugriffen...................................................................................46
5.9
Zweite Index−Tabelle...........................................................................................................47
5.10
Key Zugriffe auf mehrere Zeilen........................................................................................49
5.11
Explizite Arbeitsbereiche....................................................................................................51
5.12
Interne Tabellen sortieren....................................................................................................52
5.13
Interne Tabellen miteinander verknüpfen...........................................................................52
5.14
Geschachtelte LOOPs.........................................................................................................54
5.15
Modifizieren einzelner Komponenten.................................................................................57
5.16
Modifizieren mehrerer Zeilen.............................................................................................58
5.17
Einfügen einer int. Tab........................................................................................................60
5.18
Löschen mehrerer Zeilen.....................................................................................................61
5.19
Löschen eines Sets von Zeilen............................................................................................62
5.20
Bestimmte Tabelleneinträge zählen....................................................................................64
5.21
Großen Datenbestand filtern...............................................................................................65
5.22
Geschachtelte Tab. oder EXTRACT...................................................................................66
5.23
Anzahl Tabelleneinträge ermitteln......................................................................................69
5.24
Tabelle vom Typ SORTED (4.0)........................................................................................70
5.25
Tabelle vom Typ HASHED (4.0).......................................................................................71
6
String manipulation.............................................................................................................................74
6.1
Spezielle Operatoren im IF (CA, ...).....................................................................................74
6.2
String Verknüpfung...............................................................................................................74
6.3
String Verknüpfung II...........................................................................................................75
6.4
Trennen von Textstrings........................................................................................................76
6.5
Löschen führender Leerstellen..............................................................................................77
6.6
Nutzung strlen().....................................................................................................................78
6.7
Initialisierung.........................................................................................................................79
7
Typisierung...........................................................................................................................................80
7.1
Typisierte vs. nicht typ. Parameter........................................................................................80
7.2
Typisierte vs. nicht typ. Feldsymbole...................................................................................82
8
If, Case,
8.1
8.2
8.3
9
Field Conversion...................................................................................................................................86
9.1
Field Types I and P.................................................................................................................86
....(Performance und Wartbarkeit).....................................................................................83
If vs. Case...............................................................................................................................83
While vs. Do...........................................................................................................................84
Case vs. Perform i Of ............................................................................................................84
ii
SAP_Tips
Table of Contents
9.2
9.3
9.4
9.5
Literals Type C and Type I....................................................................................................86
Konstanten vom Typ F..........................................................................................................87
Berechnungen.........................................................................................................................88
Gemischte Datentypen..........................................................................................................88
iii
1.
Performant programmieren
1.1
Vorwort
Dieses soll als Entscheidungshilfe, Handbuch und Checkliste bei der Analyse von Performance−Problemen
dienen.
Im folgenden werden zunächst kurz die wesentlichen Eigenschaften von Open SQL und Native SQL
dargestellt. Beim Open SQL wird der Schwerpunkt auf die zu 4.0 neuen Möglichkeiten gelegt.
Im weiteren werden konkrete Empfehlungen und Codierungsbeispiele für die Bereiche:
1.
SQL−Interface
2.
Interne Tabellen
3.
String Manipulation
4.
Allgemeine Hinweise (noch in Arbeit)
5.
Typisierung
6.
If; Case; performance und Wartbarkeit
7.
Feldkonvertierung
kurz beschrieben.
In dieser Version wurden die Beispiele neu gruppiert, so daß zusammenhängende Beispiele nah aufgeführt
sind. Für das Thema Parallel Cursor wurde ein passenderes Beispiel entwickelt. Einige Empfehlungen
wurden verfeinert dargestellt.
Anregungen, Verbesserungsvorschläge, Korrekturen und Nachfragen werden jederzeit gerne
entgegengenommen.
1.2
Open SQL
Die Open SQL Schnittstelle will Anwendungsentwickler(inne)n einen ausreichenden Sprachumfang an die
Hand geben, der eine DB−unabhängige Entwicklung effizienter Anwendungen erlaubt. Diese Schnittstelle
zeichnet sich aus durch:
1.
Gute Integration in ABAP−Entwicklungsumgebung (Syntaxprüfung!).
2.
Komfortable Datenausgabe und −übergabe über interne Tabellen, Zuordnung der Felder von
SELECT−Klausel nach INTO−Klausel „by number“ und „by name“.
3.
Alle Statements werden gegenüber der DB gleichartig aufbereitet. Dadurch entstehen wenige
1.
Performant programmieren
1
SAP_Tips
unterschiedliche Statements und der Statement Cache wird gut ausgenutzt.
Die Funktionalität des Open SQL wurde durch verschiedene Erweiterungen in Richtung des ANSI/ISO
Standards zu 3.0 erweitert. Hierzu gehört im wesentlichen:
1.
Aggregatfunktionen (AVG, MAX, MIN, SUM, COUNT) sowie die GROUP BY Klausel.
2.
Cursor Operationen (OPEN, FETCH, CLOSE). Hierdurch können parallel Cursor geöffnet werden
und Zugriffe beliebig verschränkt durchgeführt werden.
3.
Möglichkeit der Angabe von DISTINCT
Dies erlaubt es, die Eindeutigkeit von Ergebnismengen vom DBS zu fordern und kann damit auch zu einer
erheblichen Reduzierung der Datenmenge, die von der DB zum Applikations−Server transportiert werden,
beitragen.
ACHTUNG:
DISTINCT erfordert Sortierungen auf dem DB−Server und ist daher relativ teuer, sofern kein Index
verwendet werden kann. Anfragen mit DISTINCT können bei gepufferten Tabellen nicht auf dem Puffer
abgewickelt werden und führen immer zu einem DB−Zugriff. Also: DISTINCT nur angeben, falls tatsächlich
mit Duplikaten gerechnet werden muß (z.B. bei Projektions−Views) und diese nicht toleriert werden können.
Bei einer drastischen Reduktion der zu transportierenden Datenmenge ist DISTINCT natürlich ebenfalls
empfehlenswert.
4.
Verwendung von Feldleisten im SELECT
Es war bis zu Release 3.0 im OPEN SQL nicht möglich, einzelne Felder in der SELECT−Klausel anzugeben
(nur SELECT *). Sollen nur wenige Felder selektiert werden, so ist eine Selektion mit '*' auf der DB−Tabelle
nicht sinnvoll, da zu viele Daten unnötig transportiert werden.
Bis zu Release 3.0 mußte in einem solchen Fall immer zunächst ein Projektions−View im Data Dictionary
angelegt werden. Dies hatte den Zweck, die Anzahl unterschiedlicher Statements gering zu halten, um eine
möglichst gute Trefferquote im Statement−Cache zu erhalten.
Diese Technik sollte daher auch weiterhin soweit möglich beibehalten werden. Dort wo dies nicht möglich
oder sinnvoll ist, können nun auch einzelne Felder beim SELECT ausgewählt werden. Um die Anzahl der
Statements nicht durch vertauschte Feldreihenfolgen unnötig zu erhöhen, sollte sich die Reihenfolge immer
am Dictionary orientieren.
5.
INNER JOINS
Joins sind erst mit 4.0 verfügbar.
Unter 3.0. wird statt dessen entweder ein entsprechender View definiert oder die Subquery−Technik
verwendet ( −> FOR ALL ENTRIES )
1.
Performant programmieren
2
SAP_Tips
1.3
Native SQL
Die Native SQL Schnittstelle reicht alle Kommandos möglichst unverändert an das DBS weiter. Durch die
weitgehende Umgehung der SAP−Datenbankschnittstelle ist hier die große Gefahr der Erzeugung von
Inkonsistenzen bei der Durchführung von ändernden Operationen gegeben. Es erfolgt beispielsweise keine
Tabellenprotokollierung, synchrone Matchcodes werden nicht aktualisiert und es findet auch keine
Synchronisation mit dem SAP DB−Puffer statt. Hinzu kommt ein beträchtliches Potential von
Portierungsproblemen.
1.3
Native SQL
3
2 Sammlung typischer (Performance−)Probleme
und Lösungsvorschläge
Dieser Abschnitt enthält eine Sammlung typischer Performance−Fallen und Lösungen dazu.
2.1
Realisierung von Subqueries
2.2
Zugriffe auf logisch verknüpfte Tabellen
In diesem Abschnitt werden die verschiedenen Möglichkeiten vorgestellt und bewertet, wie auf logisch
verknüpfte Tabellen zugegriffen werden kann. Der besseren Lesbarkeit wegen orientiert sich die Reihenfolge
an der Release−Verfügbarkeit der einzelnen Techniken.
2.2.1
Geschachteltes SELECT
Die einfachste und auch am weitesten verbreitete Möglichkeit, Daten aus logisch verknüpften Tabellen zu
lesen, ist ein geschachteltes SELECT−Statement. Hierbei werden innerhalb einer SELECT−Schleife um die
treibende Tabelle für jeden darin selektierten Satz einzelne SELECTS auf die abhängige(n) Tabelle(n)
abgesetzt, um die anhängigen Sätze zu lesen:
SELECT * FROM KNA1 [WHERE cond1].
SELECT * FROM KNB1
WHERE LIFNR = KNA1−LIFNR
[AND cond2].
PERFORM DO_SOMETHING USING kna1 knb1.
ENDSELECT.
ENDSELECT.
Der eklatante Nachteil dieser Lösung besteht darin, daß für jeden Satz, der in der äußeren SELECT−Schleife
verarbeitet wird, ein SELECT gegen die Datenbank und damit u.U. auch über das Netz abgesetzt wird. Ist die
von der äußeren Selektion bestimmte Treffermenge sehr groß, so entstehen in einer Client/Server Umgebung
außerordentlich hohe Kommunikationskosten zwischen Applikations− und Datenbank−Server!
Mit Release 3.0 stehen im Open SQL klar bessere Techniken zur Verfügung.
2.2.2
SELECT FOR ALL ENTRIES
Das mit Release 3.0 neu in den Sprachumfang des Open SQL hinzugekommene SELECT−Konstrukt erlaubt
eine mengenorientierte Verarbeitung gegenüber der Datenbank. Im Gegensatz zum geschachtelten SELECT,
bei dem in der inneren SELECT−Schleife satzweise auf die Datenbank zugegriffen wird, ist es mit dem
"SELECT FOR ALL ENTRIES" möglich, mehrere Sätze auf einmal von der Datenbank zu lesen. Das
folgende Beispiel soll dies verdeutlichen:
DATA: kna1_tab LIKE kna1 OCCURS 100 WITH HEADER LINE,
knb1_tab LIKE knb1 OCCURS 1000 WITH HEADER LINE.
2
Sammlung typischer (Performance−)Probleme und Lösungsvorschläge
4
SAP_Tips
SELECT * FROM kna1 INTO TABLE kna1_tab PACKAGE SIZE 100
[WHERE cond1].
SORT kna1_tab.
SELECT * FROM knb1 INTO TABLE knb1_tab
FOR ALL ENTRIES IN kna1_tab
WHERE kunnr = kna1_tab−kunnr
[AND cond2].
SORT knb1_tab.
i = 0.
LOOP AT kna1_tab.
IF sy−tabix = 1.
READ TABLE knb1_tab INDEX 1.
ENDIF.
WHILE sy−subrc = 0 AND kna1_tab−kunnr = knb1_tab−kunnr.
PERFORM DO_SOMETHING USING kna1_tab knb1_tab.
ADD 1 TO i.
READ TABLE knb1_tab INDEX i.
ENDWHILE.
IF SY−SUBRC <> 0. EXIT. ENDIF.
ENDLOOP.
REFRESH kna1_tab.
ENDSELECT.
In der äußeren SELECT−Schleife wird die KNA1 portionsweise in eine interne Tabelle KNA1_TAB
eingelesen und nach dem Primärschlüssel sortiert. Ob, wie in diesem Beispiel, mit ABAP−Mitteln sortiert
wird (diese Sortierung findet auf dem Applikations−Server statt) oder aber mit Datenbankmitteln (in diesem
Fall hätte die äußere SELECT−Schleife mit dem Zusatz ORDER BY PRIMARY KEY versehen werden
müssen) hängt von der Einschränkung cond1 ab.
Ein ORDER BY PRIMARY KEY ist nur dann zu empfehlen, wenn die Datenbank aufgrund der
WHERE−Bedingung sowieso den Primärindex verwenden würde (z.B. bei einer Einschränkung über die
Kundennummer: WHERE kunnr BETWEEN ... AND ...) und damit nicht explizit sortieren müßte. Wenn
allerdings aufgrund der Bedingung cond1 die Abarbeitung der Selektion über einen Sekundärindex erfolgt, so
wäre die Angabe des ORDER BY PRIMARY KEY kontraproduktiv, da dann die Datenbank die
Ergebnismenge explizit sortieren müßte. Letzteres ist bei großen Datenmengen eine recht teure und
CPU−intensive Operation, die die zentrale Resource "Datenbank−Server" unnötig belasten würde.
Für jede der in der äußeren SELECT−Schleife in die interne Tabelle KNA1_TAB gelesene Datenportion
werden alle zugehörigen abhängigen Sätze über den SELECT FOR ALL ENTRIES mit einem (bzw. wenigen
− s.u.) Datenbankzugriffen in die interne Tabelle KNB1_TAB eingelesen. Um die beiden internen Tabellen
KNA1_TAB und KNB1_TAB danach effizient abmischen zu können, ist es sinnvoll auch die KNB1_TAB zu
sortieren, um dann in einem geschachtelten Loop die gewünschte Verarbeitung auszuführen.
Die Größe der bei einem SELECT FOR ALL ENTRIES angegeben internen Tabelle ist im Prinzip nicht
limitiert. Allerdings ist zu beachten, daß die Umsetzung des SELECT FOR ALL ENTRIES in SQL−Syntax
durch die Datenbankschnittstelle zu einer Veroderung (bei manchen Datenbanksystemen Unionbildung) der
WHERE−Bedingung für jede Zeile der internen Tabelle führt. So würde z.B. obiges SELECT FOR ALL
ENTRIES in folgendes SQL−Statement transformiert:
SELECT * FROM knb1
WHERE kunnr = kna1_tab−kunnr[1] [AND cond2]
2
Sammlung typischer (Performance−)Probleme und Lösungsvorschläge
5
SAP_Tips
OR kunnr = kna1_tab−kunnr[2] [AND cond2]
...
OR kunnr = kna1_tab−kunnr[100] [AND cond2].
Wie man sieht, können abhängig von der Größe der internen Tabelle sehr komplexe SQL−Statements
entstehen. Die Datenbankschnittstelle zerlegt ein solches komplexes Statement abhängig von der Größe der
internen Tabelle (teilweise sogar von der Breite der in der WHERE−Bedingung verwendeten Felder) in
mehrere einzelne Statements, die den Restriktionen des jeweiligen Datenbanksystems gerade noch genügen,
und vereinigt dann die Ergebnisse der Einzelstatements. Duplikate werden dabei vom ABAP eliminiert.
Die Angabe einer Aggregatfunktion ist im Zusammenhang mit dem FOR ALL ENTRIES Zusatz unsinnig!
2.3
Portionsweises Einlesen
Wenn portionsweise Daten eingelesen werden sollen, dann müssen zwei Fälle unterschieden werden:
·
Einlesen geschieht innerhalb einer Transaktion.
In diesem Fall kann das Einlesen mit Hilfe des SELECT Zusatzes PACKAGE SIZE reguliert werden. Das
Ergebnis der Selektion wird in eine interne Tabelle gestellt.
·
Bildwechsel oder sonstige Transaktionsbeendigung erforderlich.
Ein Beispiel wäre hier das portionsweise Anzeigen und Weitersuchen nach Interaktion mit dem Benutzer
oder auch der Fall, daß Portionen von Daten mit einem RFC verarbeitet werden sollen.
In einem solchen Fall müssen die Daten mit dem SELECT−Zusatz "UP TO n ROWS" eingelesen werden.
Der letzte erhaltene Key wird gemerkt und dann zum Wiederaufsetzen verwendet. Voraussetzung ist dabei
natürlich, daß sortiert gelesen wird.
2.4
Mengen Insert, Update, Delete
2.4.1
Wie portionieren? Wann commit?
Das Durchführen großer Mengen von Änderungsoperationen erfordert vom DBS das Schreiben/Verwalten
von großen Datenmengen, um ein Rücksetzen (Rollback) der durchgeführten Operationen jederzeit zu
ermöglichen. Der hierfür benötigte Speicher kann dabei zu einem Engpaß werden (z.B.
Rollback−Segment−Überlauf) oder auch die maximale Anzahl von Sperr−einträgen (Lock−Table Überlauf).
Es muß daher dafür gesorgt werden, daß die Änderungsoperationen in bestimmten Abständen bestätigt
(Committed) werden.
Ein Rücksetzen vor einen solchen Commit−Zeitpunkt ist dann aber nicht mehr automatisch möglich. Es muß
vielmehr ein Wiederaufsetzmechanismus vorgesehen werden, der die bereits durchgeführten Änderungen
berücksichtigt.
2.3
Portionsweises Einlesen
6
SAP_Tips
Eine typische Größe für ORACLE Rollback−Segmente im SAP Umfeld beträgt etwa 100MB. Diese Grenze
sollte jedoch nie voll ausgeschöpft werden, da auch die Daten für Änderungen anderer Prozesse im gleichen
ROLLBACK−Segment gesichert werden könnten.
Die Verwendung eines Task−Handler−Commit Aufrufes (COMMIT WORK) bringt den Nachteil mit sich,
daß ein Prozeßwechsel stattfinden kann und daher alle geöffneten Cursor geschlossen werden müssen. Aus
diesem Grund wird ab 3.0 ein spezieller Funktionsbaustein zur Durchführung von Datenbank−Commits
angeboten:
CALL FUNCTION 'DB_COMMIT'.
WICHTIG: Bei Selektionen, die nach dem Commit fortgeführt werden sollen, muß der Cursor mit dem
Zusatz WITH HOLD eröffnet werden !
2.4.2
Array−Update
Sind wenige Felder in vielen Sätzen zu ändern, so geschieht dies am besten durch die Definition einer
(Update−fähigen) View über die Schlüsselfelder und die Felder, die geändert werden sollen.
Die gleiche Technik kann übrigens auch beim INSERT angewandt werden, wenn viele Felder mit dem
Initialwert belegt werden sollen. Es ist dann aber darauf zu achten, daß die fraglichen Spalten mit NOT
NULL im Dictionary stehen.
2.5
Existenzprüfung
SELECT * FROM dbtab UP TO 1 ROWS
WHERE (Bedingung).
ENDSELECT.
IF sy−subrc EQ 0.
exists = 'TRUE'.
ENDIF.
Ab Release 3.0 kann auch anstatt '*' ein einzelnes Feld angegeben werden, um die Menge der transportierten
Daten zu reduzieren. Bei der Verwendung von Feldern ist jedoch wie immer zu berücksichtigen, daß dadurch
die Anzahl der verschiedenen Statements steigt und die Trefferrate im Statement−Cache sinken kann.
Von der Verwendung von COUNT(*) ist abzuraten, da in diesem Fall von der DB die gesamte Treffermenge
zusammengestellt werden muß. Bei Oracle kommt noch erschwerend hinzu, daß dabei in dem Falle, daß
keine WHERE−Bedingung angegeben ist, über die Daten anstatt (wie es vernünftig wäre) über den Index
gegangen wird.
2.6
ORDER BY versus ABAP Sort
Um den DB−Server zu entlasten, ist i.a. Sortieren im ABAP vorzuziehen.
Es ist zu beachten, daß das Sortieren großer Datenmengen auf dem DB−Server Auswirkungen auf die
Performance aller Anwender hat, während das Sortieren im ABAP nur den jeweiligen Applikations−Server in
2.4.2
Array−Update
7
SAP_Tips
die Knie zwingt.
Kann allerdings für die Sortierung ein Index verwendet werden, so entstehen auf DB−Seite kaum zusätzliche
Kosten für die Sortierung.
2.7 DISTINCT versus ABAP SORT + DELETE ADJACENT
DUPLICATES
Wenn DISTINCT die Ergebnismenge deutlich einschränkt, dann ist die Verwendung in Select vorzuziehen.
Distinct macht aber nur Sinn auf Views, die nicht über den kompletten Primärschlüssel verfügen. Ansonsten
ist die Ergebnismenge ohnehin eindeutig. Erstellung von Statistiken
2.8
Wann und wie Puffern?
Das Puffern von Tabellen erhöht in vielen Fällen die Lesegeschwindigkeit. Die Angabe von genauen
Zahlenwerten hier ist nicht unproblematisch, da die Systembelastung eine gewaltige Rolle spielt. Außerdem
ist zu berücksichtigen, ob eine Tabelle extra für den Lesezugriff in den Puffer geladen werden muß oder ob
sie sich schon darin befindet. Bei den Werten für den DB Zugriff ist entscheidend, ob Platten I/O erforderlich
ist oder nicht.
Für ein eingeschwungenes, mittelmäßig belastetes System, bei dem sich also die Daten bereits im Puffer
befinden, muß für das Lesen eines Satzes − SELECT SINGLE − einer gepufferten Tabelle mit ca. 0,2 ms
gerechnet werden, während für das Lesen auf ungepufferten Tabellen mit ca. 5 ms gerechnet werden muß.
2.7
DISTINCT versus ABAP SORT + DELETE ADJACENT DUPLICATES
8
3
Tips & Tricks
Die konkreten Beispiele können durch den Tester/Entwickler temporär modifiziert werden. Nach dem
Verlassen der TRX gehen die Änderungen verloren.
In den folgenden Kapiteln sind die Beispiele aus „Tips & Tricks“ dokumentiert. Die Überschriften
entsprechen den Auswahlmöglichkeiten.
Anmerkungen:
·
Das Kapitel „Allgemeine Hinweise“ ist noch in Entwicklung.
·
Beispiele werden ständig verbessert bzw. erweitert
·
Bei einem Neuaufbau des CF3 müssen bestimmte Beispieltabellen ggf. erst initialisert werden.
·
SFLIGHT, CUSTOMERS
·
Mit der Bereitstellung DM2 wird die Entwicklung und Pflege von Tips & Tricks in diesem
System durchgeführt.
3
Tips & Tricks
9
4
SQL Interface
4.1
Projektion im Select
Select *
SELECT * FROM VZZKOKO
WHERE BUKRS = '0020'
AND SANLF = '300'
AND RKEY1 = '0001821840011'.
ENDSELECT.
Select mit Feldliste
SELECT DGUEL_KK BZUSAGE
FROM VZZKOKO
INTO CORRESPONDING FIELDS OF VZZKOKO
WHERE BUKRS = '0020'
AND SANLF = '300'
AND RKEY1 = '0001821840011'.
ENDSELECT.
Bewertung
Falls nur einige Spalten einer Tabelle benötigt werden, nutzen Sie entweder einen VIEW oder geben Sie die
Feldliste im Select an. Je mehr Treffer (z.B. VDBEKI zu einem Darlehen) desto größer der
Performancegewinn. 50% der Felder eingelesen > ca. 40% Zugriffszeit gespart
−> Views z.Zt ZZVBEKI, ZZVBEKI2, ZZVBEKIALL, VDBEVI
4.2
Select ... Where vs. Select + Check
Select + Check
SELECT
* FROM VDBEKI
WHERE BUKRS = '0020'
4
SQL Interface
10
SAP_Tips
AND RANL
= '0000012310014'.
CHECK VDBEKI−DBUDAT = '16.06.1997'.
ENDSELECT.
Select mit Where Bedingung
SELECT
* FROM VDBEKI
WHERE BUKRS = '0020'
AND RANL
= '0000012310014'
AND DBUDAT = '16.06.1997'.
ENDSELECT.
Bewertung
Bekannte Bedingungen sollten in der WHERE−Bedingung angegeben werden. Dies ist meist performanter
als die Prüfung innerhalb Select−Endselect mit CHECK. Die Datenbank kann dann einen passenden Index
nutzen. Beachten Sie vorhandene Indizes bei der Formulierung eines
Selects. Die Reihenfolge der Felder in der WHERE−Bedingung sollte die Reihenfolge des Index
widerspiegeln.
−> Indizes zu einer Tabelle via se12
4.3
Select mit (Primär−)Index−Unterstützung
Select mit Schlüssellücke
SELECT
* FROM VDARL
WHERE BUKRS
AND RANL
= '0020'
= '0000012310014'.
ENDSELECT.
Select ohne Lücke im (Primär−)Index
SELECT
* FROM VDARL
WHERE BUKRS
AND SARCHIV
AND RANL
4.3
= '0020'
=''
= '0000012310014'.
Select mit (Primär−)Index−Unterstützung
11
SAP_Tips
ENDSELECT.
Bewertung
Für häufig genutzte Zugriffe muß stets versucht werden, einen Index zu nutzen. Zugriffe mit Teilschlüsseln
sind immer dann nicht performant, wenn die Lücke vor dem entscheidenden Kriterium ist:
Beispiel: VDARL:Nach BUKRS hat der Index noch nichts eingrenzen können, es sind noch alle 145.000
Sätze relevant.
−> damit müssen im schlechtesten Fall alle Eintragungen durchsucht werden.
4.4
Select mit Buffer−Unterstützung
Select auf ungepuffterte Tab.
SELECT SINGLE * FROM T100
BYPASSING BUFFER
WHERE
SPRSL = 'D'
AND ARBGB = '00'
AND MSGNR = '999'.
Select mit gepufferter Tab.
SELECT SINGLE * FROM T100
WHERE
SPRSL = 'D'
AND ARBGB = '00'
AND MSGNR = '999'.
Bewertung
Häufig genutzte Customizing−Tabellen sollten gepuffert werden. −> z.B. für Online−Anwendungen
Stamm− und Bewegungsdaten werden nicht im SAP−Umfeld gepuffert. In Batch−Programmen
−> Tabelle einmal in interne Tabelle
−> READ BINARY SEARCH
Folgende Zusätze zum SELECT verhindern einen Zugriff auf den Puffer:
FOR UPDATE, ORDER BY (verschieden vom Primärschlüssel), COUNT,
AVG, MAX, MIN, SUM, DISTINCT, IS NULL, native SQL ... .
4.4
Select mit Buffer−Unterstützung
12
SAP_Tips
4.5
Select und Aggregatsfunktionen
Select ... Where + Check
C4A = '000'.
SELECT * FROM T100
WHERE SPRSL = 'D' AND
ARBGB = '00'.
CHECK: T100−MSGNR > C4A.
C4A = T100−MSGNR.
ENDSELECT.
Select mit Aggregatsfunktion
SELECT MAX( MSGNR ) FROM T100 INTO C4A
WHERE SPRSL = 'D' AND
ARBGB = '00'.
Bewertung
Diese Zugriffe bringen nur dann einen Performancevorteil, wenn ausschließlich z.B. die Anzahl von Sätzen
oder die Summe einer Tabellenspalte benötigt wird und nicht aber die eigentlichen Daten aus der
Tabelle.
.
4.6
Select mit ORDER BY vs. SORT
Select mit Order BY
SELECT * FROM VDBEKI INTO TABLE I_VDBEKI
WHERE BUKRS = '0020'
AND RANL < '000000200000'
ORDER BY DBLDAT.
Select mit SORT
SELECT * FROM VDBEKI INTO TABLE I_VDBEKI
WHERE BUKRS = '0020'
4.5
Select und Aggregatsfunktionen
13
SAP_Tips
AND RANL < '000000200000'.
SORT I_VDBEKI BY DBLDAT.
Bewertung
Ein ORDER BY ist nur dann zu empfehlen, wenn die Datenbank aufgrund der WHERE−Bedingungen den
gleichen Index verwendet und damit nicht explizit sortieren müßte.
Letzeres ist bei großen Datenmengen eine recht teure und CPU−intensive Operation, die die zentrale
Resource Datenbankserver unnötig belasten würde.
Warnung: ORDER BY verschieden vom Primärschlüssel geht immer am SAP−Puffer vorbei !
4.7
Existenzprüfung
Select UP TO 1 ROWS
SELECT * FROM VDBEKI UP TO 1 ROWS
WHERE BUKRS = '0020'
AND RANL
= '0000012310014'.
ENDSELECT.
IF SY−SUBRC = 0.
" exists = 'TRUE'.
ENDIF.
Select mit Exit
SELECT * FROM VDBEKI
WHERE BUKRS = '0020'
AND RANL
= '0000012310014'.
EXIT.
ENDSELECT.
IF SY−SUBRC = 0.
" exists = 'TRUE'.
ENDIF.
4.7
Existenzprüfung
14
SAP_Tips
Bewertung
Zum Überprüfen der Existenz mindestens eines Datensatzes zur angegebenen WHERE−Be−dingung auf
einer DB−Tabelle, sollte der Konstrukt mit UP to 1 ROWS verwandt werden. Im Falle der Existenz ist dieser
wesentlich schneller. Ab 3.0 kann ein SELECT SINGLE auch mit Teilschlüssel benutzt werden.
Select ... Into Table t
Select + Append statement
REFRESH I_VDBEKI.
SELECT * FROM VDBEKI
WHERE BUKRS = '0020'
AND RANL = '0000012310014'.
APPEND I_VDBEKI.
ENDSELECT.
Select Into Table
SELECT * FROM VDBEKI
INTO TABLE I_VDBEKI
WHERE BUKRS = '0020'
AND RANL = '0000012310014'.
Bewertung
Into Table ist immer schneller als die Nutzung von Append im Select−Endselect−loop.
Beim SELECT ... INTO TABLE itab mit dem Zusatz PACKAGE SIZE n werden nicht alle selektierten
Zeilen auf einmal in die interne Tabelle gestellt, sondern in Paketen von n Zeilen. Der Inhalt von itab wird
von jedem neuen Paket überschrieben. So kann vermieden werden, daß die interne Tabelle zu groß wird.
4.8
Nutzung von Like/Between
Select mit LIKE
SELECT
* FROM VDBEPP
WHERE BUKRS
AND RANL
4.8
= '0020'
LIKE '000001231%'.
Nutzung von Like/Between
15
SAP_Tips
ENDSELECT.
Select mit BETWEEN
SELECT
* FROM VDBEPP
WHERE BUKRS
= '0020'
AND RANL BETWEEN '0000012310000'
AND '0000012319999'.
ENDSELECT.
Bewertung
Die Nutzung von LIKE ist in vielen Fällen weniger performant als die Verwendung vom BETWEEN.
Auch hier wird im SQL−Trace eine größere Differenz angezeigt.
4.9
Nutzung von RANGE/IN
Notwendiger Vorlauf für Beispiel
REFRESH RANGE_VDARL.
RANGE_VDARL−SIGN = 'I'.
RANGE_VDARL−OPTION = 'EQ'.
SELECT * FROM VDARL UP TO 100 ROWS
WHERE BUKRS ='0020'.
RANGE_VDARL−LOW = VDARL−RANL.
APPEND RANGE_VDARL.
ENDSELECT.
Select mit RANGE
SELECT
* FROM VDARL
WHERE BUKRS = '0020'
AND SARCHIV = ' '
AND RANL
4.9
IN RANGE_VDARL.
Nutzung von RANGE/IN
16
SAP_Tips
ENDSELECT.
Notwendiger Vorlauf für Beispiel
REFRESH RANGE_VDARL.
RANGE_VDARL−SIGN = 'I'.
RANGE_VDARL−OPTION = 'EQ'.
SELECT * FROM VDARL UP TO 100 ROWS
WHERE BUKRS ='0020'.
RANGE_VDARL−LOW = VDARL−RANL.
APPEND RANGE_VDARL.
ENDSELECT.
Select Single im LOOP
LOOP AT RANGE_VDARL.
SELECT SINGLE * FROM VDARL
WHERE BUKRS
= '0020'
AND SARCHIV = ' '
AND RANL
= RANGE_VDARL−LOW.
ENDLOOP.
Bewertung
Die Tabelle Range_vdarl hat 100 Eintragungen. Die Nutzung von Range ist hier günstiger Achtung: Auch die
Oracle−Version unter 3.0 verträgt nur max. 255 Einträge.
4.10
Select single vs. Select−Endselect
Select−Endselect
SELECT * FROM VDARL
WHERE BUKRS
AND SARCHIV
AND RANL
4.10
= '0020'
=''
= '0000012310014'.
Select single vs. Select−Endselect
17
SAP_Tips
ENDSELECT.
Select single
SELECT SINGLE * FROM VDARL
WHERE BUKRS
= '0020'
AND SARCHIV
AND RANL
=''
= '0000012310014'.
Bewertung
Falls alle Felder des Primärindex bekannt sind, sollte ein Select Single genutzt werden. Der Select Single
benötigt genau eine Kommunikation mit dem Datenbank−Server, der Select−Endselect dagegen zwei.
4.11
Select−Endselect vs. Array−Select
Select Into Table t + Loop at t.
SELECT * FROM VDBEKI
INTO TABLE I_VDBEKI
WHERE BUKRS = '0020'
AND RANL = '0000012310014'.
LOOP AT I_VDBEKI.
ENDLOOP.
LOOP AT I_VDBEKI.
ENDLOOP.
Select ... Endselect.
SELECT * FROM VDBEKI
WHERE BUKRS = '0020'
AND RANL = '0001821840011'.
ENDSELECT.
SELECT * FROM VDBEKI
WHERE BUKRS = '0020'
4.11
Select−Endselect vs. Array−Select
18
SAP_Tips
AND RANL = '0001821840011'.
ENDSELECT.
Bewertung
Falls Sie Daten mehrfach nutzen müssen, bringt die Nutzung der internen Tabelle einen Performancevorteil.
Bei großen Tabellen wächst der Page−Bereich des Programms an. Selbst wenn die Verarbeitung nur einmal
erfolgt, ist ein nicht unerheblicher Vorteil meßbar (2. Loop und 2. Select aussternen)
4.12
Select vs. Read
Select vs. Read für Customizing−Tabellen
Select Single
DO 1000 TIMES.
SELECT SINGLE * FROM TZK0A
WHERE SPRAS ='D'
AND
RANTYP = '1'
AND
SKOART = '0920'.
ENDDO.
Read Binary Search
SELECT * FROM TZK0A INTO TABLE I_TZK0A.
SORT I_TZK0A BY MANDT SPRAS RANTYP SKOART.
DO 1000 TIMES.
KEY−MANDT = '001'.
KEY−SPRAS = 'D'.
KEY−RANTYP = '1'.
KEY−SKOART = '0920'.
READ TABLE I_TZK0A WITH KEY KEY BINARY SEARCH.
ENDDO.
Bewertung
4.12
Select vs. Read
19
SAP_Tips
Read binary Search ist besonders für Programme zu empfehlen, die einen größeren Bestand auswerten. Für
Online−Trx. ist das Select Single im Vorteil.
Batch:
−> Einmaliges Einlesen der gesamten TZK0A : ca. 90 msec.
−> Lesen Kondition aus interner Tabelle (für unterschiedliche
Konditionsarten)
−> In diesem Fall wird ein größerer Performancevorteil im Vergleich zum Select single erreicht.
4.13
Select und OR
Select und OR
Klassischer OR
SELECT * FROM TZK01
WHERE SKOAREF = '0000'
AND ( SBEWZITI = 'KEIG'
OR SBEWZITI = 'TBB' ).
ENDSELECT.
Aufgelöster OR
SELECT * FROM TZK01
WHERE ( SKOAREF = '0000'
AND SBEWZITI = 'KEIG' )
OR ( SKOAREF = '0000'
AND
SBEWZITI = 'TBB' ).
ENDSELECT.
Bewertung
Beide Bsp. liefern das gleiche Ergebnis. Tabelle hat 223 Einträge (Konditionsarten) Empfehlungen zu
kompliziert aufgebauten OR−Klauseln müssen nicht in jedem Fall schneller sein. Jedoch ist bei größeren
Tabellen und selektiv gehaltenen Feldern die rechte Seite schneller.
4.13
Select und OR
20
SAP_Tips
4.14
Select mit View
Geschachtelte Select−Statements
SELECT * FROM VDBEKI
WHERE BUKRS = '0020'
AND RANL = '0000012310014'.
SELECT
* FROM VDBEPI
WHERE BUKRS
= '0020'
AND
= VDBEKI−RBELKPFD.
RBELKPFD
ENDSELECT.
ENDSELECT.
Select mit View
SELECT * FROM ZZVBEKIALL
WHERE BUKRS = '0020'
AND RANL = '0000012310014'.
ENDSELECT.
Bewertung
Die Nutzung eines Views ist immer einem geschachtelten Select−statement vorzuziehen. Selbst bei
identischer Feldanzahl ist der View schneller Der View ZZVBEKI2 hat weniger Felder als ZZVBEKIALL.
Der Performancegewinn zum Gesamtview ist beachtlich (ca. 50 %). Test Sie selbst in Tips und Tricks. Auch
der View VDBEVI bringt Performancegewinn.
−> Datenbankviews (Typ D) finden Sie über se12 oder se15 Z.Zt: ZZVBEKI,
ZZVBEKI2,
ZZVBEKIALL und VDBEVI
−> Zum Pflege der Customizing−Tabellen gibt es Pflege−Views
4.15
Select mit View II
Vollständiger Index
SELECT * FROM ZZVBEKIALL
4.14
Select mit View
21
SAP_Tips
WHERE BUKRS = '0020'
AND RANL = '0000012310014'
AND SANLF = '300'.
ENDSELECT.
letztes Indexfeld fehlt
SELECT * FROM ZZVBEKIALL
WHERE BUKRS = '0020'
AND RANL = '0000012310014'.
ENDSELECT.
Bewertung
Die Indizes der Basistabellen werden auf den View übertragen. Die vollständige Angabe der Indexfelder ist
performanter. Der Effekt tritt bei Views mit geringer Feldanzahl stärker auf z.B. ZZVBEKI2
4.16
Select mit FOR ALL ENTRIES
Geschachtelter Select
SELECT * FROM VDBEKI
WHERE BUKRS = '0020'
AND RANL = '0000012310014'.
SELECT
* FROM VDBEPI
WHERE BUKRS
= '0020'
AND
= VDBEKI−RBELKPFD.
RBELKPFD
ENDSELECT.
ENDSELECT.
Select mit FOR ALL ENTRIES
SELECT * FROM vdbeki into table i_vdbeki
WHERE BUKRS = '0020'
AND RANL = '0000012310014'.
4.16
Select mit FOR ALL ENTRIES
22
SAP_Tips
IF SY−DBCNT > 0.
SELECT * FROM VDBEPI
FOR ALL entries in i_vdbeki
where bukrs = '0020'
and rbelkpfd = i_vdbeki−rbelkpfd.
ENDSELECT.
ENDIF.
Bewertung
Liegt kein DB−View vor, ist die Lösung mit FOR ALL ENTRIES vorzuziehen. Vor allem dann, wenn der
Inhalt der internen Tabelle i_vdbeki noch weiter verwendet werden soll. Die 2.Select−Schleife mit dem
Zusatz FOR ALL ENTRIES ist im Vgl. mit einer LOOP−SELECT−SINGLE−Lösung ebenfalls
performanter, siehe Beispiel 'Nutzung RANGE/IN'. Der Zusatz FOR ALL ENTRIES kann auch mit dem
Zusatz INTO TABLE, also mit einem Array−Fetch verwandt werden. Alternativen: Siehe Beispiele 'Select
mit View', 'parallele CURSOR' . *
Das Verhalten des SELECT FOR ALL ENTRIES kann mit Profilparametern beeinflußt werden. Eine
vernünftige Kombination dieser Parameter wäre:
rsdb/max_blocking_factor
= 40
rsdb/min_blocking_factor
= 5
rsdb/max_in_blocking_factor = 250
rsdb/min_in_blocking_factor = 40
Änderungen sollten mit dem Systemadministrator abgesprochen werden, da sie das gesamte R/3−System
betreffen ! *
4.17
Select vs. OPEN CURSOR
select vs. OPEN CURSOR
DATA C1 TYPE CURSOR.
DATA D1 TYPE CURSOR.
Mit OPEN CURSOR
OPEN CURSOR C1 FOR
SELECT * FROM VDBEKI
4.17
Select vs. OPEN CURSOR
23
SAP_Tips
WHERE BUKRS = '0020'
AND RANL = '0000012310014'.
DO.
FETCH NEXT CURSOR C1 INTO VDBEKI.
IF SY−SUBRC <> 0. CLOSE CURSOR C1. EXIT. ENDIF.
OPEN CURSOR D1 FOR
SELECT * FROM VDBEPI
WHERE BUKRS = '0020'
AND RBELKPFD = VDBEKI−RBELKPFD.
DO.
FETCH NEXT CURSOR D1 INTO VDBEPI.
IF SY−SUBRC <> 0. CLOSE CURSOR D1. EXIT. ENDIF.
ENDDO.
ENDDO.
Klassischer Select
SELECT * FROM VDBEKI
WHERE BUKRS = '0020'
AND RANL = '0000012310014'.
SELECT * FROM VDBEPI
WHERE BUKRS
= '0020'
AND RBELKPFD = VDBEKI−RBELKPFD.
ENDSELECT.
ENDSELECT.
Bewertung
Das obige Konstrukt mit der eigenen CURSOR−Verwaltung ist ähnlich unperformant wie der geschachtelte
SELECT, da immer wieder der CURSOR der inneren Tabelle geöffnet werden muß. Alternativen dazu sind
das Lesen über einen DB−VIEW, der SELECT mit FOR ALL ENTRIES oder die parallele
4.17
Select vs. OPEN CURSOR
24
SAP_Tips
CURSOR−Definition (siehe Beispiele). *
Generell gilt für die Performanz zum Lesen abhängiger Tabellen: *
Selektivität des äußeren SELECTs:
niedrig
mittel
hoch
−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−
geschachtelter SELECT (klassisch)
−
o
SELECT mit FOR ALL ENTRIES
parallele CURSOR
+
+
o
o
+
o
−
(+:gute o:mittlere −:schlechte Performanz)
Kann kein DB−View angelegt werden (z.B. wegen redundanter Datenhaltung etc. ), dann stellt die Lösung
mit SELECT FOR ALL ENTRIES in allen Fällen einen guten Kompromiß dar.
4.18
Select vs. parallele CURSOR
select vs. parallele CURSOR
DATA C1 TYPE CURSOR.
DATA C2 TYPE CURSOR.
Mit parallele CURSOR
OPEN CURSOR C1
FOR SELECT * FROM VDBEKI
WHERE BUKRS = '0020'
AND RBELKPFD BETWEEN '0000001500' AND '0000001550'
ORDER BY PRIMARY KEY.
OPEN CURSOR C2
FOR SELECT * FROM VDBEPI
WHERE BUKRS = '0020' ORDER BY PRIMARY KEY.
DO.
FETCH NEXT CURSOR C1 INTO VDBEKI.
IF SY−SUBRC <> 0. CLOSE CURSOR C1. EXIT. ENDIF.
4.18
Select vs. parallele CURSOR
25
SAP_Tips
IF SY−INDEX = 1.
FETCH NEXT CURSOR C2 INTO VDBEPI.
ENDIF.
WHILE SY−SUBRC = 0 AND VDBEKI−RBELKPFD = VDBEPI−RBELKPFD.
FETCH NEXT CURSOR C2 INTO VDBEPI.
ENDWHILE.
IF SY−SUBRC <> 0. CLOSE CURSOR C2. EXIT. ENDIF.
ENDDO.
Klassischer Select
SELECT * FROM VDBEKI
WHERE BUKRS = '0020'
AND RBELKPFD BETWEEN '0000001500' AND '0000001550'.
SELECT * FROM VDBEPI
WHERE BUKRS
= '0020'
AND RBELKPFD = VDBEKI−RBELKPFD.
ENDSELECT.
ENDSELECT.
Bewertung
Vorteil der parallelen Cursor: Auf die innere Tabelle wird nur einmal eine OPEN CURSOR abgesetzt.
Nachteil: Einschränkung der übergeordneten Tabelle kann nicht auf die untergeordnete weitergegeben
werden. Folgerung: Je selektiver die Bedingung in der übergeordneten Tabelle ist, um so mehr überwiegt der
Nachteil. Im obigen Beispiel überwiegt der Vorteil, siehe auch Testprogramm ZSTEST07.
4.19
Dynamischer vs. statischen SELECT
DATA: TAB_NAME(10).
DATA: WA LIKE VDBEKI.
Dynamischer SELECT
TAB_NAME = 'VDBEKI'.
4.19
Dynamischer vs. statischen SELECT
26
SAP_Tips
SELECT * FROM (TAB_NAME) INTO WA
WHERE BUKRS = '0020'
AND RBELKPFD BETWEEN '0000001500' AND '0000001550'.
ENDSELECT.
Klassischer Select
SELECT * FROM VDBEKI
WHERE BUKRS = '0020'
AND RBELKPFD BETWEEN '0000001500' AND '0000001550'.
ENDSELECT.
Bewertung
Angabe des Namens der Datenbanktabelle oder des Views zur Laufzeit bei den Aufrufen von SELECT,
INSERT, UPDATE, MODIFY und DELETE. * Der Name einer Datenbanktabelle oder eines Views kann als
Inhalt eines Feldes und somit dynamisch angegeben werden. Diese dynamische Angabe des Tabellennamens
im Quelltext ist in der Regel unperformanter als die statische, da interne Kontrollblöcke erst zur Laufzeit
generiert werden können. *
4.20
Array−Insert vs. Einzelsatz−Insert
DATA: TAB LIKE SFLIGHT OCCURS 100 WITH HEADER LINE.
SELECT * FROM SFLIGHT INTO TABLE TAB.
DELETE SFLIGHT FROM TABLE TAB.
Einzelzeilen Inserts
LOOP AT TAB.
INSERT INTO SFLIGHT VALUES TAB.
ENDLOOP.
DATA: TAB LIKE SFLIGHT OCCURS 100 WITH HEADER LINE.
SELECT * FROM SFLIGHT INTO TABLE TAB.
DELETE SFLIGHT FROM TABLE TAB.
Array−Insert
4.20
Array−Insert vs. Einzelsatz−Insert
27
SAP_Tips
INSERT SFLIGHT FROM TABLE TAB.
Bewertung
Die Summe von n Einzel−Inserts benötigt immer mehr Zeit als ein einmaliger Insert von n Tabellen−Zeilen.
Dieser Massen−Update durch den Zusatz FROM TABLE ist auch möglich für UPDATE, DELETE und
MODIFY. Der Performanzgewinn geht aber im Falle des MODIFYs verloren. Um obiges Beispiel zu testen,
sollte die Demo−Tabelle SFLIGHT mit dem Report RSBCDAT1 gefüllt worden sein. Mit diesen Daten ist
der Array−Insert im obigen Beispiel 8 mal schneller.
4.21
Spalten−Update vs. klass. Update
UPDATE SFLIGHT SET SEATSOCC = SEATSOCC + 1.
Einzelzeilen Updates
SELECT * FROM SFLIGHT.
SFLIGHT−SEATSOCC =
SFLIGHT−SEATSOCC − 1.
UPDATE SFLIGHT.
ENDSELECT.
UPDATE SFLIGHT SET SEATSOCC = SEATSOCC + 1.
Spalten−Update
UPDATE SFLIGHT
SET SEATSOCC = SEATSOCC − 1.
Bewertung
Falls nur wenige Spalten einer Tabelle verändert werden sollen, ist die Nutzung des Spalten−Update
vorzuziehen. Um obiges Beispiel zu testen, sollte die Demo−Tabelle SFLIGHT mit dem Report RSBCDAT1
gefüllt worden sein. Mit diesen Daten ist der Spalten−Update im obigen Beispiel 6 mal schneller.
4.22
Select mit Unterabfrage (4.0)
Geschachtelter Select
SELECT * FROM VDARL WHERE BUKRS = '0020'
AND SARCHIV = ' '
AND RANL BETWEEN '0003000100000' AND
4.21
Spalten−Update vs. klass. Update
28
SAP_Tips
'0003000200000' .
SELECT * FROM VDBEPP WHERE BUKRS = VDARL−BUKRS
AND RANL = VDARL−RANL
AND DTRANS < '19950101'.
WRITE: / vdarl−ranl.
ENDSELECT.
ENDSELECT.
Select mit Unterabfrage
SELECT * FROM VDARL AS F1
WHERE BUKRS = '0020'
AND SARCHIV = ' '
AND RANL BETWEEN '0003000100000' AND
'0003000200000'
AND RANL IN
( SELECT RANL FROM VDBEPP
WHERE BUKRS = F1~BUKRS
AND RANL = F1~RANL
AND DTRANS < '19950101' ) .
WRITE: / vdarl−ranl.
ENDSELECT.
Bewertung
So können Sie komplexe Abfragen effizient programmieren. In der ersten Anweisung werden alle Daten von
der Datenbank an die Anwendung übergeben, wo sie dann gefiltert werden. In der zweiten Anweisung
werden die Daten in der Datenbank gefiltert, wobei ein Alias verwendet werden muß. Dies bedeutet aber, daß
weniger Daten von der Datenbank an die Anwendung übergeben werden müssen. Diese Methode hat
gegenüber der normalen SELECT−Anweisung einige Einschränkungen, z.B. kein SELECT SINGLE.
4.21
Spalten−Update vs. klass. Update
29
SAP_Tips
4.23
Select mit INNER JOIN (4.0)
Geschachtelter Select
SELECT * FROM VDBEKI
WHERE BUKRS = '0020'
AND RANL = '0002000500010'.
SELECT
* FROM VDBEPI
WHERE BUKRS
= '0020'
AND
= VDBEKI−RBELKPFD.
RBELKPFD
WRITE: / vdbeki−bukrs, vdbeki−rbelkpfd, vdbepi−dfaell.
ENDSELECT.
ENDSELECT.
INNER JOIN
SELECT F1~BUKRS F1~RBELKPFD F2~DFAELL INTO
(VDBEKI−BUKRS, VDBEKI−RBELKPFD, VDBEPI−DFAELL)
FROM VDBEKI AS F1 INNER JOIN VDBEPI AS F2
ON F1~BUKRS = F2~BUKRS
AND F1~RBELKPFD = F2~RBELKPFD
WHERE F1~BUKRS = '0020'
AND F1~RANL = '0002000500010'.
WRITE: / vdbeki−bukrs, vdbeki−rbelkpfd, vdbepi−dfaell.
ENDSELECT.
Bewertung
Bei einem inneren Join legt das System eine temporäre Tabelle an, die die Kombinationen der Zeilen der
Datenbanktabellen enthält, deren Werte die mit ON <condition> angegebene logische Bedingung erfüllt
eine Ergebnismenge. Es ist unerheblich, ob die Bedingung in der ON− oder in der WHERE−Klausel
angegeben wird; das Ergebnis eines inneren Join ist dasselbe.
Wenn Sie in der Feldliste Feldnamen verwenden, die in beiden Tabellen eines inneren Join vorkommen,
4.23
Select mit INNER JOIN (4.0)
30
SAP_Tips
müssen Sie sie eindeutig machen, indem Sie ihnen einen Aliasnamen und eine Tilde voranstellen. Sie
geben den Aliasnamen in der FORM−Klausel mit dem Zusatz AS <aliasname> an.
Neben seiner einfachen Form hat ein Join auch den Vorteil, daß nur eine Anweisung in der Datenbank
ausgeführt wird. Allerdings hat ein Join den Nachteil, daß redundante Daten aus der äußeren Tabelle im
Ergebnis erscheinen, wenn eine 1:N−Beziehung zwischen der äußeren und der inneren Tabelle besteht. Dies
kann die Menge der von der Datenbank an die Anwendung übergebenen Daten drastisch erhöhen.
Wenn Sie also einen Join verwenden, sollten Sie aus diesem Grund nur die Felder im View oder der
Feldliste benutzen, die Sie wirklich benötigen. Die Performance eines Join hängt stark von der
Performance des verwendeten Datenbank−Optimizer ab, besonders wenn der Join sich über mehr als zwei
Tabellen erstreckt.
Ein Beispiel für einen Join mit mehr als zwei Tabellen finden Sie in der Schlüsselwortdokumentation zu
JOIN. Innere und äußere Joins arbeiten immer am Puffer vorbei.
4.24
Select mit LEFT OUTER JOIN (4.0)
Geschachtelter Select
SELECT * FROM VDBEKI
WHERE BUKRS = '0020'
AND RANL = '0002000500010'.
SELECT
* FROM VDBEPI
WHERE BUKRS
= '0020'
AND
= VDBEKI−RBELKPFD.
RBELKPFD
WRITE: / vdbeki−bukrs, vdbeki−rbelkpfd, vdbepi−dfaell.
ENDSELECT.
ENDSELECT.
LEFT OUTER JOIN
SELECT F1~BUKRS F1~RBELKPFD F2~DFAELL
INTO
(VDBEKI−BUKRS, VDBEKI−RBELKPFD, VDBEPI−DFAELL)
FROM VDBEKI AS F1 LEFT OUTER JOIN VDBEPI AS F2
ON F1~BUKRS = F2~BUKRS
4.24
Select mit LEFT OUTER JOIN (4.0)
31
SAP_Tips
AND F1~RBELKPFD = F2~RBELKPFD
WHERE F1~BUKRS = '0020'
AND F1~RANL = '0002000500010'.
WRITE: / vdbeki−bukrs, vdbeki−rbelkpfd, vdbepi−dfaell.
ENDSELECT.
Bewertung
Ein LEFT OUTER JOIN enthält wie ein innerer Join Kombinationen der Zeilen aus den Datenbanktabellen,
deren Werte die in der ON <condition>−Klausel angegebene logische Bedingung erfüllen (Join−Bedingung).
Die Zeilen der linken Tabelle, die die Bedingung nicht erfüllen, werden an das Ende der Ergebnismenge
angehängt. D.h. die von der Datenbank erzeugte temporäre Tabelle enthält, im Gegensatz zu einem inneren
Join, immer die gesamte linke Tabelle. Die Felder der rechten Tabelle für diese Zeilen werden auf
Datenbankebene mit NULL−Werten gefüllt; ABAP kennt immer noch nur Initialwerte, nicht Nullen. Die
normale WHERE−Bedingung wird dann auf die temporäre Tabelle angewendet. *
Im Gegensatz zum INNER JOIN hängt das Ergebnis eines LEFT OUTER JOIN sehr wohl davon ab, ob die
Bedingung in der ON− oder in der WHERE−Klausel angegeben wurde. Ohne WHERE−Klausel enthält die
Ergebnistabelle immer alle Zeilen der linken Tabelle, während mit einer WHERE−Klausel Sätze aus der
linken Tabelle herausgenommen werden können. *
Die Anweisung LEFT OUTER JOIN enthält bestimmte Einschränkungen. Eine dieser Einschränkungen
besteht darin, daß eine Selektion auf ein Feld der rechten Tabelle in einer AND−Bedingung angegeben
werden muß. *
In einem LEFT OUTER JOIN erscheinen Tabelleneinträge auch dann in der Join−Ergebnistabelle, wenn es
keinen entsprechenden Datensatz in der rechten Tabelle gibt. In der Ergebnismenge ist dies also das
Equivalent zu einer geschachtelten SELECT−Anweisung. * Innere und äußere Joins arbeiten immer am
Puffer vorbei. *
4.24
Select mit LEFT OUTER JOIN (4.0)
32
5
Interne Tabellen
5.1
Interne Tabellen kopieren.
Interne Tabellen kopieren
DATA: TAB_SRC TYPE TAB1_100 WITH HEADER LINE,
TAB_DEST TYPE TAB1_100 WITH HEADER LINE,
FLAG.
IF FLAG = SPACE.
DO 100 TIMES.
APPEND TAB_SRC.
ENDDO.
FLAG = 'X'.
ENDIF.
Zu Fuß: Int. Tab. kopieren
Table TAB_SRC hat 100 Sätze mit jeweils 10 Bytes.
REFRESH TAB_DEST.
LOOP AT TAB_SRC INTO TAB_DEST.
APPEND TAB_DEST.
ENDLOOP.
DATA: TAB_SRC TYPE TAB1_100 WITH HEADER LINE,
TAB_DEST TYPE TAB1_100 WITH HEADER LINE,
FLAG.
IF FLAG = SPACE.
DO 100 TIMES.
APPEND TAB_SRC.
5
Interne Tabellen
33
SAP_Tips
ENDDO.
FLAG = 'X'.
ENDIF.
Lassen wir den Kernel arbeiten...
Table TAB_SRC hat 100 Sätze mit jeweils 10 Bytes.
TAB_DEST[] = TAB_SRC[].
Bewertung
Int. Tab. kann mit MOVE wie jedes andere Datenobjekt kopiert werden. Wenn eine int. Tab eine Kopfzeile
hat kann die Tabelle mit itab[] angesprochen werden.
5.2
Interne Tabellen vergleichen
Interne Tabellen vergleichen
DATA: TAB1 TYPE TAB1_100 WITH HEADER LINE,
TAB2 TYPE TAB1_100 WITH HEADER LINE,
L1 TYPE I,
L2 TYPE I,
TAB_DIFFERENT,
FLAG.
IF FLAG = SPACE.
DO 100 TIMES.
APPEND: TAB1, TAB2.
ENDDO.
FLAG = 'X'.
ENDIF.
Zu Fuß: Int. Tab. vergleichen.
Tabelle TAB1 und TAB2 sind jeweils mit 100 Sätzen (Satzlänge 100 Bytes gefüllt.
DESCRIBE TABLE: TAB1 LINES L1,
5.2
Interne Tabellen vergleichen
34
SAP_Tips
TAB2 LINES L2.
IF L1 <> L2.
TAB_DIFFERENT = 'X'.
ELSE.
TAB_DIFFERENT = SPACE.
LOOP AT TAB1.
READ TABLE TAB2 INDEX SY−TABIX.
IF TAB1 <> TAB2.
TAB_DIFFERENT = 'X'. EXIT.
ENDIF.
ENDLOOP.
ENDIF.
IF TAB_DIFFERENT = SPACE.
" ...
ENDIF.
DATA: TAB1 TYPE TAB1_100 WITH HEADER LINE,
TAB2 TYPE TAB1_100 WITH HEADER LINE,
FLAG.
IF FLAG = SPACE.
DO 100 TIMES. APPEND: TAB1, TAB2. ENDDO.
FLAG = 'X'.
ENDIF.
Lassen wir den Kernel arbeiten...
Tabelle TAB1 und TAB2 sind jeweils mit 100 Sätzen (Satzlänge 100 Bytes gefüllt.
IF TAB1[] = TAB2[].
" ...
5.2
Interne Tabellen vergleichen
35
SAP_Tips
ENDIF.
Bewertung
Int. Tab. können wie andere Datenobjekte logisch verglichen werden. Zwei int. Tab. sind gleich wenn
− dieselbe Zeilenanzahl vorhanden und
− jedes Zeilenpaar gleich ist.
Wenn eine int. Tab. eine Kopfzeile hat, kann die Tabelle mit itab[] angesprochen werden.
Löschen doppelter Sätze
Löschen doppelter Sätze einer internen Tabelle
DATA: TAB_SRC TYPE TAB1_1000 WITH HEADER LINE,
TAB_DEST TYPE TAB1_1000 WITH HEADER LINE,
PREV_LINE LIKE LINE OF TAB_DEST,
FLAG.
IF FLAG = SPACE.
DO 500 TIMES.
TAB_SRC−K = SY−INDEX.
APPEND TAB_SRC.
APPEND TAB_SRC.
ENDDO.
FLAG = 'X'.
ENDIF.
TAB_DEST[] = TAB_SRC[].
Zu Fuß: Löschen doppelter Sätze.
Tabelle TAB_DEST hat 1000 Sätze mit jeweils 100 Bytes und beinhaltet 500 doppelte Sätze.
READ TABLE TAB_DEST INDEX 1 INTO PREV_LINE.
LOOP AT TAB_DEST FROM 2.
IF TAB_DEST = PREV_LINE.
5.2
Interne Tabellen vergleichen
36
SAP_Tips
DELETE TAB_DEST.
ELSE.
PREV_LINE = TAB_DEST.
ENDIF.
ENDLOOP.
Notwendiger Vorlauf für Beispiel
DATA: TAB_SRC TYPE TAB1_1000 WITH HEADER LINE,
TAB_DEST TYPE TAB1_1000 WITH HEADER LINE,
FLAG.
IF FLAG = SPACE.
DO 500 TIMES.
TAB_SRC−K = SY−INDEX.
APPEND TAB_SRC.
APPEND TAB_SRC.
ENDDO.
FLAG = 'X'.
ENDIF.
TAB_DEST[] = TAB_SRC[].
Lassen wir den Kernel arbeiten...
Tabelle TAB_DEST hat 1000 Sätze mit jeweils 100 Bytes und beinhaltet 500 doppelte Sätze.
DELETE ADJACENT DUPLICATES FROM TAB_DEST COMPARING K.
Bewertung
Mit der neuen DELETE Variante DELETE ADJACENT DUPLICATES
Der Prozeß des Löschens doppelter Sätze kann dem Kernel überlassen werden.
5.2
Interne Tabellen vergleichen
37
SAP_Tips
5.3
Anhängen an eine Tabelle
Anhängen einer int. tab. an eine andere
DATA: TAB_SRC TYPE TAB1_100 WITH HEADER LINE,
TAB_DEST TYPE TAB1_100 WITH HEADER LINE,
FLAG.
IF FLAG = SPACE.
DO 500 TIMES.
APPEND TAB_SRC.
ENDDO.
FLAG = 'X'.
ENDIF.
TAB_DEST[] = TAB_SRC[].
Tabelle TAB_SRC und TAB_DEST sind beide mit 500 Einträgen gefüllt; jede mit 100 Bytes. TAB_SRC
wird Zeile für Zeile an TAB_DEST angehängt
LOOP AT TAB_SRC.
APPEND TAB_SRC TO TAB_DEST.
ENDLOOP.
Notwendiger Vorlauf für Beispiel
DATA: TAB_SRC TYPE TAB1_100 WITH HEADER LINE,
TAB_DEST TYPE TAB1_100 WITH HEADER LINE,
FLAG.
IF FLAG = SPACE.
DO 500 TIMES.
APPEND TAB_SRC.
ENDDO.
FLAG = 'X'.
5.3
Anhängen an eine Tabelle
38
SAP_Tips
ENDIF.
TAB_DEST[] = TAB_SRC[].
Lassen wir den Kernel arbeiten...
Tabelle TAB_SRC und TAB_DEST sind beide mit 500 Einträgen gefüllt; jede mit 100 Bytes. TAB_SRC
wird in einem Step an TAB_DEST gehängt.
APPEND LINES OF TAB_SRC TO TAB_DEST.
Bewertung
Mit der neuen APPEND Variante: APPEND LINES OF itab1 TO itab2. Der Prozeß des Anhängens an eine
andere Tabelle kann dem Kernel überlassen werden.
5.4
Aufbau von Tabellen ohne Dupletten
Aufbau sort. Tab.: READ/INSERT vs. APPEND/SORT/DELETE
DATA: TAB_SRC TYPE TAB1_1000 WITH HEADER LINE,
TAB_DEST TYPE TAB1_1000 WITH HEADER LINE,
FLAG.
IF FLAG = SPACE.
TAB_SRC−K(15) = SY−ABCDE.
SHIFT TAB_SRC−K(15) CIRCULAR LEFT BY 6 PLACES.
DO 500 TIMES.
TAB_SRC−K+15(5) = SY−INDEX.
APPEND TAB_SRC.
APPEND TAB_SRC.
SHIFT TAB_SRC−K(15) CIRCULAR LEFT.
ENDDO.
FLAG = 'X'.
ENDIF.
Ein Step Zugriff
5.4
Aufbau von Tabellen ohne Dupletten
39
SAP_Tips
Tabelle TAB_SRC ist mit 1.000 Sätzen gefüllt von denen 500 versch. Keys haben.
REFRESH TAB_DEST.
LOOP AT TAB_SRC.
READ TABLE TAB_DEST WITH KEY K = TAB_SRC−K BINARY SEARCH.
IF SY−SUBRC <> 0.
INSERT TAB_SRC INTO TAB_DEST INDEX SY−TABIX.
ENDIF.
ENDLOOP.
Notwendiger Vorlauf für Beispiel
DATA: TAB_SRC TYPE TAB1_1000 WITH HEADER LINE,
TAB_DEST TYPE TAB1_1000 WITH HEADER LINE,
FLAG.
IF FLAG = SPACE.
TAB_SRC−K(15) = SY−ABCDE.
SHIFT TAB_SRC−K(15) CIRCULAR LEFT BY 6 PLACES.
DO 500 TIMES.
TAB_SRC−K+15(5) = SY−INDEX.
APPEND TAB_SRC.
APPEND TAB_SRC.
SHIFT TAB_SRC−K(15) CIRCULAR LEFT.
ENDDO.
FLAG = 'X'.
ENDIF.
Drei Steps: copy, sort, delete Dupletten
Tabelle TAB_SRC ist mit 1.000 Sätzen gefüllt von denen 500 versch. Keys haben.
REFRESH TAB_DEST.
5.4
Aufbau von Tabellen ohne Dupletten
40
SAP_Tips
LOOP AT TAB_SRC.
APPEND TAB_SRC TO TAB_DEST.
ENDLOOP.
SORT TAB_DEST BY K.
DELETE ADJACENT DUPLICATES FROM TAB_DEST COMPARING K.
Bewertung
Wenn die Datenmenge klein ist (< 20 Sätze) oder Lesezugriffe während des Füllens der Tabelle notwendig
sind, dann ist der linke Zugriff mit READ/INSERT die richtige Wahl. Wenn jedoch das Datenvolumen
größer ist und Lesezugriffe auf die komplett gefüllte Tabelle notwendig sind, dann ist der 'Drei Steps'
Algorithmus zu bevorzugen.
5.5
Aufbau sortierter Tabellen
Aufbau einer sort. int. Tabelle: READ/INSERT vs. APPEND/SORT
Ein Step: READ/INSERT
DATA: TAB_SRC TYPE TAB1_1000 WITH HEADER LINE,
TAB_DEST TYPE TAB1_1000 WITH HEADER LINE,
FLAG.
IF FLAG = SPACE.
TAB_SRC−K = SY−ABCDE.
DO 1000 TIMES.
APPEND TAB_SRC.
SHIFT TAB_SRC−K CIRCULAR.
ENDDO.
FLAG = 'X'.
ENDIF
TAB_DEST enthält 1000 Einträge
REFRESH TAB_DEST.
LOOP AT TAB_SRC.
5.5
Aufbau sortierter Tabellen
41
SAP_Tips
READ TABLE TAB_DEST WITH KEY K = TAB_SRC−K BINARY SEARCH.
INSERT TAB_SRC INTO TAB_DEST INDEX SY−TABIX.
ENDLOOP.
Zwei Steps: APPEND, dann SORT
DATA: TAB_SRC TYPE TAB1_1000 WITH HEADER LINE,
TAB_DEST TYPE TAB1_1000 WITH HEADER LINE,
FLAG.
IF FLAG = SPACE.
TAB_SRC−K = SY−ABCDE.
DO 1000 TIMES.
APPEND TAB_SRC.
SHIFT TAB_SRC−K CIRCULAR.
ENDDO.
FLAG = 'X'.
ENDIF.
*TAB_DEST is filled with 1000 entries
REFRESH TAB_DEST.
LOOP AT TAB_SRC.
APPEND TAB_SRC TO TAB_DEST.
ENDLOOP.
SORT TAB_DEST BY K.
Bewertung
Wenn die Datenmenge klein ist (< 20 Sätze) oder Lesezugriffe während des Füllens der Tabelle notwendig
sind, dann ist der linke Zugriff mit READ/INSERT die richtige Wahl. Wenn jedoch das Datenvolumen
größer ist und Lesezugriffe auf die komplett gefüllte Tabelle notwendig sind, dann ist der 'Zwei Steps'
Algorithmus zu bevorzugen.
5.5
Aufbau sortierter Tabellen
42
SAP_Tips
5.6
Aufbau von summierten Tabellen
Aufbau einer summ. und sort. Tabelle: READ/INSERT vs. COLLECT/SORT
COLLECT Umschreibung mit READ BINARY
DATA: TAB_SRC TYPE TAB3_10000 WITH HEADER LINE,
TAB_DEST TYPE TAB3_10000 WITH HEADER LINE,
FLAG.
IF FLAG = SPACE.
DO 2 TIMES.
TAB_SRC−K(10) = SY−ABCDE.
DO 5000 TIMES.
SHIFT TAB_SRC−K(10) LEFT CIRCULAR.
TAB_SRC−K+10(10) = SY−INDEX.
APPEND TAB_SRC.
ENDDO.
ENDDO.
FLAG = 'X'.
ENDIF.
FREE TAB_DEST.
*Tabelle TAB_SRC ist mit 10.000 Sätzen gefüllt von denen 5.000 versch. Keys haben.
LOOP AT TAB_SRC.
READ TABLE TAB_DEST WITH KEY K = TAB_SRC−K BINARY SEARCH.
IF SY−SUBRC = 0.
ADD: TAB_SRC−VAL1 TO TAB_DEST−VAL1,
TAB_SRC−VAL2 TO TAB_DEST−VAL2.
MODIFY TAB_DEST INDEX SY−TABIX.
5.6
Aufbau von summierten Tabellen
43
SAP_Tips
ELSE.
INSERT TAB_SRC INTO TAB_DEST INDEX SY−TABIX.
ENDIF.
ENDLOOP.
Sammeln mit COLLECT
DATA: TAB_SRC TYPE TAB3_10000 WITH HEADER LINE,
TAB_DEST TYPE TAB3_10000 WITH HEADER LINE,
FLAG.
IF FLAG = SPACE.
DO 2 TIMES.
TAB_SRC−K(10) = SY−ABCDE.
DO 5000 TIMES.
SHIFT TAB_SRC−K(10) LEFT CIRCULAR.
TAB_SRC−K+10(10) = SY−INDEX.
APPEND TAB_SRC.
ENDDO.
ENDDO.
FLAG = 'X'.
ENDIF.
FREE TAB_DEST.
*Tabelle TAB_SRC ist with 10.000 Sätzen gefüllt, von denen 5.000 verschiedene Keys haben.
LOOP AT TAB_SRC.
COLLECT TAB_SRC INTO TAB_DEST.
ENDLOOP.
SORT TAB_DEST BY K.
Bewertung
5.6
Aufbau von summierten Tabellen
44
SAP_Tips
Wenn man eine summierende Funktion benötigt, dann COLLECT verwenden ! READ BINARY läuft in O(
log2( n ) ) Zeit, und der Index der int. Tabelle muß bei jedem INSERT neu justiert werden. COLLECT
jedoch benutzt einen Hash−Algorithmus und ist deshalb unabhämgig von der Anzahl der Einträge ( z.B. O( 1
)) und braucht daher keinen Tabellen−Index. Wenn man den letzten Sort benutzt wird die interne Tabelle erst
nach dem COLLECT sortiert. *
Für kleine Datenmengen ist der READ/INSERT Zugriff nicht schlecht, aber bei größeren Datenmengen (>
1000) ist der COLLECT viel schneller. .Achtung: Beim Füllen einer int.Tab. sollte COLLECT nicht in
Kombination mit anderen füllenden Befehlen (APPEND, INSERT, MODIFY SELECT * INTO TABLE
und/oder SELECT * APPENDING TABLE) verwendet werden. Wenn man COLLECT mit den anderen
Befehlen mischt kann der Hash−Algorithmus nicht verwendet werden. In diesem Fall wird eine normale
lineare Suche durchgeführt, die dramatisch langsamer ist: O ( n ).
5.7
Lineare Suche oder binary search
Lineare Suche oder binary search
Lineare Suche einer internen Tabelle
DATA: TAB TYPE TAB1_1000 WITH HEADER LINE,
FLAG.
IF FLAG = SPACE.
DO 1000 TIMES.
APPEND TAB.
ENDDO.
FLAG = 'X'.
ENDIF.
*Table TAB ist gefüllt mit 1000 Sätzen von je 100 Byte. Der READ endet mit SY−SUBRC=4
READ TABLE TAB WITH KEY K = 'X'.
Binary search einer int. Tab.
DATA: TAB TYPE TAB1_1000 WITH HEADER LINE,
FLAG.
IF FLAG = SPACE.
DO 1000 TIMES.
APPEND TAB.
5.7
Lineare Suche oder binary search
45
SAP_Tips
ENDDO.
FLAG = 'X'.
ENDIF.
*Table TAB ist gefüllt mit 1000 Sätzen von je 100 Byte. Der READ endet mit SY−SUBRC=4
READ TABLE TAB WITH KEY K = 'X' BINARY SEARCH.
Bewertung
Wenn int.Tab. viele Einträge (>20) haben, ist eine lineare Suche durch alle Einträge sehr zeit−intensiv.
Versuchen die Tabelle sortiert zu halten and binary search benutzen. Wenn eine Tab. n Sätze hat, dann
braucht eine lineare Suche O( n ) Zeit während binary search nur O( log2( n ) ) Zeit benötigt.
5.8
Versch. Arten von Schlüsselzugriffen
Schlüsselzugriff: Implizite gegen explizite Keyfeld−Spezifikation
Zugriff über impliziten default Key
DATA: TAB TYPE TAB2_100 WITH HEADER LINE,
FLAG.
IF FLAG = SPACE.
DO 30 TIMES.
APPEND TAB.
ENDDO.
FLAG = 'X'.
ENDIF.
*TAB ist mit 30 Einträgen mit jeweils 500 Bytes gefüllt. Der READ endet mit SY−SUBRC=4
MOVE SPACE TO TAB.
TAB−K = 'X'.
READ TABLE TAB BINARY SEARCH.
Zugriff über expliziten Key.
DATA: TAB TYPE TAB2_100 WITH HEADER LINE,
5.8
Versch. Arten von Schlüsselzugriffen
46
SAP_Tips
FLAG.
IF FLAG = SPACE.
DO 30 TIMES.
APPEND TAB.
ENDDO.
FLAG = 'X'.
ENDIF.
*TAB ist mit 30 Einträgen mit jeweils 500 Bytes gefüllt. Der READ endet mit SY−SUBRC=4
READ TABLE TAB WITH KEY K = 'X' BINARY SEARCH.
Bewertung
Wenn möglich sollten die Keyfelder für den expliziten Zugriff gefüllt sein. Andernfalls müssen sie
dynamisch vom Run−Time−System errechnet werden.
5.9
Zweite Index−Tabelle
Anlegen einer Sek−Index Tabelle um linearen Zugriff zu vermeiden.
Keine Sek−Index Tab. => Lineare Suche
DATA: TAB TYPE TAB1_1000 WITH HEADER LINE,
FLAG.
IF FLAG = SPACE.
TAB−DATE = SY−DATUM + 500.
DO 1000 TIMES.
APPEND TAB.
SUBTRACT 1 FROM TAB−DATE.
ENDDO.
FLAG = 'X'.
ENDIF.
*Tab. TAB ist mit 1000 Einträgen gefüllt. Der READ findet den 500. Eintrag.
5.9
Zweite Index−Tabelle
47
SAP_Tips
READ TABLE TAB WITH KEY DATE = SY−DATUM.
IF SY−SUBRC = 0.
" ...
ENDIF.
Binary search mit Sek−Index Tab.
DATA: TAB
TYPE TAB1_1000 WITH HEADER LINE,
TAB_INDEX TYPE TAB_INDEX WITH HEADER LINE,
DATE
TYPE D,
FLAG.
IF FLAG = SPACE.
DATE = SY−DATUM + 500.
DO 1000 TIMES.
TAB_INDEX−DATE = TAB−DATE = DATE.
APPEND TAB.
TAB_INDEX−INDX = SY−TABIX.
APPEND TAB_INDEX.
SUBTRACT 1 FROM DATE.
ENDDO.
SORT TAB_INDEX BY DATE.
FLAG = 'X'.
ENDIF.
*Tab. TAB ist mit 1000 Einträgen gefüllt. Der READ findet den 500. Eintrag.
READ TABLE TAB_INDEX WITH KEY DATE = SY−DATUM BINARY SEARCH.
IF SY−SUBRC = 0.
READ TABLE TAB INDEX TAB_INDEX−INDX.
" ...
5.9
Zweite Index−Tabelle
48
SAP_Tips
ENDIF.
Bewertung
Benötigt man wiederholt Zugriffe auf eine int. Tab. mit versch. Keys, ist es zu empfehlen eigene
Sek.−Tabellen aufzubauen. Mit einer Sek.−Tab. kann man eine lineare Suche mit einem BINNARY
SEARCH plus einem Index Zugriff ersetzen.
5.10
Key Zugriffe auf mehrere Zeilen
Key Zugriffe auf mehrere Zeilen. LOOP/CHECK gegen LOOP.
Key Zugriff mit LOOP/CHECK
DATA:
TAB TYPE TAB2_100 WITH HEADER LINE,
FLAG.
CONSTANTS: KVAL TYPE LINE2−K VALUE 'X'.
IF FLAG = SPACE.
TAB−K = SPACE.
DO 95 TIMES.
APPEND TAB.
ENDDO.
TAB−K = KVAL.
DO 5 TIMES.
APPEND TAB.
ENDDO.
FLAG = 'X'.
ENDIF.
*Tabelle TAB hat 100 Sätze mit jeweils 500 Bytes. 5 Einträge erfüllen die Schlüsselbedingung
LOOP AT TAB.
CHECK TAB−K = KVAL.
" ...
5.10
Key Zugriffe auf mehrere Zeilen
49
SAP_Tips
ENDLOOP.
Key Zugriff mit LOOP ... WHERE
DATA:
TAB TYPE TAB2_100 WITH HEADER LINE,
FLAG.
CONSTANTS: KVAL TYPE LINE2−K VALUE 'X'.
IF FLAG = SPACE.
TAB−K = SPACE.
DO 95 TIMES.
APPEND TAB.
ENDDO.
TAB−K = KVAL.
DO 5 TIMES.
APPEND TAB.
ENDDO.
FLAG = 'X'.
ENDIF.
*Tabelle TAB hat 100 Sätze mit jeweils 500 Bytes. 5 Einträge erfüllen die Schlüsselbedingung
LOOP AT TAB WHERE K = KVAL.
" ...
ENDLOOP.
Bewertung
LOOP ... WHERE ist schneller als LOOP/CHECK, denn LOOP ... WHERE ermittelt die spezifizierte
Bedingung intern. Wie mit jedem logischem Ausdruck ist die Performance besser, wenn die Operanden des
Vergleichs vom gleichen Typ sind. Die Performance kann gesteigert werden, wenn LOOP ... WHERE mit
FROM i1 und/oder TO i2 −wenn möglich− verwendet wird.
5.10
Key Zugriffe auf mehrere Zeilen
50
SAP_Tips
5.11
Explizite Arbeitsbereiche
Explizite Arbeitsbereiche anstatt gefüllter Kopfzeilen. *># 50
Tabellen Operationen mit Kopfzeile
DATA: TAB
TYPE TAB2_100 WITH HEADER LINE,
TAB_WA LIKE LINE OF TAB.
REFRESH TAB.
*Die Zeilenlänge von Tab. TAB ist 500 Bbytes.
TAB = TAB_WA.
APPEND TAB.
Tab−Operationen mit expl. Arbeitsber.
DATA: TAB
TYPE TAB2_100 WITH HEADER LINE,
TAB_WA LIKE LINE OF TAB.
REFRESH TAB.
*Die Zeilenlänge von Tab. TAB ist 500 Bbytes.
APPEND TAB_WA TO TAB.
Bewertung
Vermeidung von unnötigen MOVEs in Arbeitsbereichen.
APPEND wa TO tab.
INSERT wa INTO tab.
COLLECT wa INTO tab.
MODIFY
tab FROM wa.
READ TABLE
LOOP AT
tab INTO wa.
tab INTO wa.
where zusätzlich...
5.11
Explizite Arbeitsbereiche
51
SAP_Tips
5.12
Interne Tabellen sortieren
interne Tabellen sortieren
Sortieren mit default Sortierschlüssel.
DATA: TAB TYPE TAB2_100 WITH HEADER LINE.
REFRESH TAB.
DO 100 TIMES.
TAB−K = 100 − SY−INDEX.
APPEND TAB.
ENDDO.
*Tabelle TAB hat 100 Sätze mit jeweils 500 Bytes.
SORT TAB.
Sortieren mit expl. Sortierschlüssel
DATA: TAB TYPE TAB2_100 WITH HEADER LINE.
REFRESH TAB.
DO 100 TIMES.
TAB−K = 100 − SY−INDEX.
APPEND TAB.
ENDDO.
Tabelle TAB hat 100 Sätze mit jeweils 500 Bytes.
SORT TAB BY K.
Bewertung
Je genauer der Sortierschlüssel angegeben wird desto schneller läuft das Programm.
5.13
Interne Tabellen miteinander verknüpfen.
Zwei sortierte int. Tab. mit gleichen Keys.
Join: loop tab1, read tab2
5.12
Interne Tabellen sortieren
52
SAP_Tips
DATA: TAB1 TYPE TAB1_1000 WITH HEADER LINE,
TAB2 TYPE TAB1_1000 WITH HEADER LINE,
FLAG.
IF FLAG = SPACE.
DO 1000 TIMES. TAB1−K = SY−INDEX.
APPEND TAB1. ENDDO.
DO 300 TIMES. TAB2−K = SY−INDEX * 2. APPEND TAB2. ENDDO.
FLAG = 'X'.
ENDIF.
*Tab. TAB1 mit 1000 Sätzen jeweils 100 Bytes. Tab. TAB2 mit 300 Sätzen jeweils 100 Bytes.
*Tab. TAB2 ist absteigend sortiert nach K.
LOOP AT TAB1.
READ TABLE TAB2 WITH KEY K = TAB1−K BINARY SEARCH.
IF SY−SUBRC = 0.
" ...
ENDIF.
ENDLOOP.
Besser: Parallele Cursor
DATA: TAB1 TYPE TAB1_1000 WITH HEADER LINE,
TAB2 TYPE TAB1_1000 WITH HEADER LINE,
I2 TYPE I,
FLAG.
IF FLAG = SPACE.
DO 1000 TIMES. TAB1−K = SY−INDEX.
APPEND TAB1. ENDDO.
DO 300 TIMES. TAB2−K = SY−INDEX * 2. APPEND TAB2. ENDDO.
FLAG = 'X'.
ENDIF.
5.12
Interne Tabellen sortieren
53
SAP_Tips
*Tab. TAB1 mit 1000 Sätzen jeweils 100 Bytes. Tab. TAB2 mit 300 Sätzen jeweils 100 Bytes.
*Tab. TAB2 ist absteigend sortiert nach K.
I2 = 1.
LOOP AT TAB1.
READ TABLE TAB2 INDEX I2.
IF SY−SUBRC <> 0. EXIT. ENDIF.
IF TAB2−K = TAB1−K.
" ...
ADD 1 TO I2.
ENDIF.
ENDLOOP.
Bewertung
Wenn TAB1 n1 und TAB2 n2 Einträge hätte, dann ist der Algorithmus O( n1 * log2( n2 ) ) um beide zu
verknüpfen; dagegen braucht der parallele Cursor Zugriff O( n1 + n2 ) Zeit. Der obige parallele Cursor
Zugriff setzt voraus, daß die TAB2 Einträge zu den TAB1 Einträgen 1 zu 1 zugeordnet sind. Falls die
Anforderung anders ist, wird die Ausprogrammierung der parallelen Cursor komplizierter, jedoch wird die
Performance−Charakteristik die gleiche sein.
5.14
Geschachtelte LOOPs
Geschachtelte LOOPs und sortierte Tabellen.
Geschachtelte LOOPs
DATA: TAB1 TYPE TAB1_100 WITH HEADER LINE,
TAB2 TYPE TAB1_1000 WITH HEADER LINE,
FLAG.
IF FLAG = SPACE.
DO 100 TIMES.
TAB1−K = TAB2−K = SY−INDEX.
APPEND TAB1.
5.14
Geschachtelte LOOPs
54
SAP_Tips
DO 10 TIMES.
APPEND TAB2.
ENDDO.
ENDDO.
FLAG = 'X'.
ENDIF.
Tabelle TAB1 hat 100 Sätze mit jeweils 100 Bytes. Tabelle TAB2 hat 10 * 100 = 1000 Sätze mit jeweils 100
Bytes.
LOOP AT TAB1.
LOOP AT TAB2 WHERE K = TAB1−K.
" ...
ENDLOOP.
ENDLOOP.
Besser: Parallele Cursors
DATA: TAB1 TYPE TAB1_100 WITH HEADER LINE,
TAB2 TYPE TAB1_1000 WITH HEADER LINE,
FLAG.
IF FLAG = SPACE.
DO 100 TIMES.
TAB1−K = TAB2−K = SY−INDEX.
APPEND TAB1.
DO 10 TIMES.
APPEND TAB2.
ENDDO.
ENDDO.
FLAG = 'X'.
5.14
Geschachtelte LOOPs
55
SAP_Tips
ENDIF.
DATA: TAB1 TYPE TAB1_100 WITH HEADER LINE,
TAB2 TYPE TAB1_1000 WITH HEADER LINE,
FLAG.
IF FLAG = SPACE.
DO 100 TIMES.
TAB1−K = TAB2−K = SY−INDEX.
APPEND TAB1.
DO 10 TIMES.
APPEND TAB2.
ENDDO.
ENDDO.
FLAG = 'X'.
ENDIF.
*Tabelle TAB1 hat 100 Sätze mit jeweils 100 Bytes. Tabelle TAB2 hat 10 * 100 = 1000 Sätze mit jeweils
100 Bytes. Tabelle TAB1 und TAB2 sind absteigend *nach K sortiert.
I2 = 1.
LOOP AT TAB1.
LOOP AT TAB2 FROM I2.
IF TAB2−K <> TAB1−K.
I2 = SY−TABIX.
EXIT.
ENDIF.
" ...
ENDLOOP.
ENDLOOP.
5.14
Geschachtelte LOOPs
56
SAP_Tips
Bewertung
Wenn TAB1 n1 und TAB2 n2 Einträge hätte, dann ist der Algorithmus O( n1 * log2( n2 ) ) um beide zu
verknüpfen; dagegen braucht der parallele Cursor Zugriff O( n1 + n2 ) Zeit. Der obige parallele Cursor
Zugriff setzt voraus, daß die TAB2 Einträge zu den TAB1 Einträgen 1 zu 1 zugeordnet sind. Falls die
Anforderung anders ist, wird die Ausprogrammierung der parallelen Cursor komplizierter, jedoch wird die
Performance−Charakteristik die gleiche sein.
5.15
Modifizieren einzelner Komponenten
Modifizieren einzelner Komponenten einer int. Tab.
Modifizieren aller Komponenten (Felder).
DATA: TAB TYPE TAB2_1000 WITH HEADER LINE,
FLAG.
IF FLAG = SPACE.
DO 500 TIMES.
APPEND INITIAL LINE TO TAB.
ENDDO.
FLAG = 'X'.
ENDIF.
*Tabelle TAB hat 500 Einträge mit jeweils 500 Bytes. Hier würden nur 8 Byte modifiziert werden, obwohl
die gesamte Leiste weggeschrieben wird.
TAB−DATE = SY−DATUM.
DO 500 TIMES.
MODIFY TAB INDEX SY−INDEX.
ENDDO.
Nur ausgewählte Komponenten modifizieren.
DATA: TAB TYPE TAB2_1000 WITH HEADER LINE,
FLAG.
IF FLAG = SPACE.
DO 500 TIMES.
5.15
Modifizieren einzelner Komponenten
57
SAP_Tips
APPEND INITIAL LINE TO TAB.
ENDDO.
FLAG = 'X'.
ENDIF.
*Tabelle TAB hat 500 Einträge mit jeweils 500 Bytes. Hier werden tatsächlich nur die 8 Byte des Feldes
DATE weggeschrieben.
TAB−DATE = SY−DATUM.
DO 500 TIMES.
MODIFY TAB INDEX SY−INDEX
TRANSPORTING DATE.
ENDDO.
Bewertung
Mit der MODIFY Variante: MODIFY itab ... TRANSPORTING f1 f2 ... Die Zeit zum Updaten der int.
Zeile kann beschleunigt werden. Je länger die Zeile desto langsamer ist die Update Zeit. Der Effekt wächst
mit der Komplexität der Typstruktur einer int. Tab.
5.16
Modifizieren mehrerer Zeilen
Modifizieren einzelner Komponenten mehrerer Zeilen
Modifzieren aller Komponenten.
DATA: TAB TYPE TAB4_100 WITH HEADER LINE.
REFRESH TAB.
DO 20 TIMES.
APPEND SY−INDEX TO TAB−INTTAB.
ENDDO.
DO 100 TIMES.
APPEND TAB.
ENDDO.
*Tabelle TAB hat 100 Einträge. Eine Zeile hat 2 Komponenten, FLAG type C und eine Tabelle INTTAB mit
5.16
Modifizieren mehrerer Zeilen
58
SAP_Tips
jeweils 20 Einträgen. Flag soll für alle 100 Zeilen *angeschaltet werden.
LOOP AT TAB.
IF TAB−FLAG IS INITIAL.
TAB−FLAG = 'X'.
ENDIF.
MODIFY TAB.
ENDLOOP.
Modifizieren nur ausgewählter Komponenten
DATA: TAB TYPE TAB4_100 WITH HEADER LINE,
WA LIKE LINE OF TAB.
REFRESH TAB.
DO 20 TIMES.
APPEND SY−INDEX TO TAB−INTTAB.
ENDDO.
DO 100 TIMES.
APPEND TAB.
ENDDO.
*Tabelle TAB hat 100 Einträge. Eine Zeile hat 2 Komponenten, FLAG type C und eine Tabelle INTTAB mit
jeweils 20 Einträgen. Flag soll für alle 100 Zeilen *angeschaltet werden.
TAB−FLAG = 'X'.
MODIFY TAB TRANSPORTING FLAG
WHERE FLAG IS INITIAL.
Bewertung
Mit der MODIFY Variante: MODIFY itab ... TRANSPORTING f1 f2 ... WHERE cond. Die Zeit zum
Updaten der int. Zeile kann beschleunigt werden. Besonders wenn Tabellen in einer Zeile mit eingebunden
sind, können diese beim Update ignoriert werden; der Performance−Gewinn ist besonders gut.
5.16
Modifizieren mehrerer Zeilen
59
SAP_Tips
5.17
Einfügen einer int. Tab.
Einfügen einer int. Tab. in eine andere int. Tab.
Zu Fuß: Einfügen einer Tabelle.
DATA: TAB_SRC TYPE TAB1_100 WITH HEADER LINE,
TAB_DEST TYPE TAB1_100 WITH HEADER LINE,
IDX
TYPE I,
FLAG.
IF FLAG = SPACE.
DO 500 TIMES.
APPEND TAB_SRC.
ENDDO.
FLAG = 'X'.
ENDIF.
TAB_DEST[] = TAB_SRC[].
*Tabelle TAB_SRC und TAB_DEST sind beide mit 500 Sätzen gefüllt; jeweils 10 Bytes. TAB_SRC wird in
TAB_DEST eingefügt Zeile für Zeile mit dem Index IDX.
IDX = 250.
LOOP AT TAB_SRC.
INSERT TAB_SRC INTO TAB_DEST INDEX IDX.
ADD 1 TO IDX.
ENDLOOP.
assen wir den Kernel arbeiten...
DATA: TAB_SRC TYPE TAB1_100 WITH HEADER LINE,
TAB_DEST TYPE TAB1_100 WITH HEADER LINE,
IDX
TYPE I,
FLAG.
5.17
Einfügen einer int. Tab.
60
SAP_Tips
IF FLAG = SPACE.
DO 500 TIMES.
APPEND TAB_SRC.
ENDDO.
FLAG = 'X'.
ENDIF.
TAB_DEST[] = TAB_SRC[].
*Tabelle TAB_SRC und TAB_DEST sind beide mit 500 Sätzen gefüllt; jeweils 10 Bytes. TAB_SRC wird in
TAB_DEST mit einem Step eingefügt mit dem Index IDX (250).
IDX = 250.
INSERT LINES OF TAB_SRC INTO TAB_DEST INDEX IDX.
Bewertung
Mit der neuen INSERT Variante: INSERT LINES OF itab1 INTO itab2 INDEX idx. Der Prozeß des
Anhängens an eine andere Tabelle kann dem Kernel überlassen werden.
5.18
Löschen mehrerer Zeilen
Löschen mehrerer Zeilen
Zu Fuß: Löschen mehrerer Zeilen.
DATA: TAB_SRC TYPE TAB2_1000 WITH HEADER LINE,
TAB_DEST TYPE TAB2_1000 WITH HEADER LINE,
FLAG.
IF FLAG = SPACE.
DO 1000 TIMES.
APPEND TAB_SRC.
ENDDO.
FLAG = 'X'.
ENDIF.
5.18
Löschen mehrerer Zeilen
61
SAP_Tips
TAB_DEST[] = TAB_SRC[].
SORT TAB_DEST BY K.
" Force an index to be allocated
Tabelle TAB_DEST hat 1000 Sätze mit jeweils 500 Bytes und Zeilen; 450 bis 550 sollen gelöscht werden.
DO 101 TIMES.
DELETE TAB_DEST INDEX 450.
ENDDO.
Lassen wir den Kernel arbeiten...
DATA: TAB_SRC TYPE TAB2_1000 WITH HEADER LINE,
TAB_DEST TYPE TAB2_1000 WITH HEADER LINE,
FLAG.
IF FLAG = SPACE.
DO 1000 TIMES.
APPEND TAB_SRC.
ENDDO.
FLAG = 'X'.
ENDIF.
TAB_DEST[] = TAB_SRC[].
SORT TAB_DEST BY K.
" Force an index to be allocated
Tabelle TAB_DEST hat 1000 Sätze mit jeweils 500 Bytes und Zeilen;450 bis 550 sollen gelöscht werden.
DELETE TAB_DEST FROM 450 TO 550.
Bewertung
Mit der neuen DELETE Variante: DELETE itab FROM ... TO ... Der Prozeß des Löschens kann dem
Kernel überlassen werden.
5.19
Löschen eines Sets von Zeilen.
Löschen eines Sets von Zeilen spezifiziert in der WHERE Klausel.
Zu Fuß: Löschen eines Sets von Zeilen
5.19
Löschen eines Sets von Zeilen.
62
SAP_Tips
DATA: TAB_SRC TYPE TAB2_1000 WITH HEADER LINE,
TAB_DEST TYPE TAB2_1000 WITH HEADER LINE,
KVAL LIKE TAB_DEST−K VALUE 'berta',
FLAG.
IF FLAG = SPACE.
DO 250 TIMES.
TAB_SRC−K = 'anton'. APPEND TAB_SRC.
TAB_SRC−K = 'berta'. APPEND TAB_SRC.
TAB_SRC−K = 'carl '. APPEND TAB_SRC.
TAB_SRC−K = 'drago'. APPEND TAB_SRC.
ENDDO.
FLAG = 'X'.
ENDIF.
TAB_DEST[] = TAB_SRC[].
*Tabelle TAB_DEST hat 1000 Sätze mit jeweils 500 Bytes, 250 entsprechen der WHERE Klausel.
LOOP AT TAB_DEST WHERE K = KVAL.
DELETE TAB_DEST.
ENDLOOP.
Lassen wir den Kernel arbeiten...
DATA: TAB_SRC TYPE TAB2_1000 WITH HEADER LINE,
TAB_DEST TYPE TAB2_1000 WITH HEADER LINE,
KVAL LIKE TAB_DEST−K VALUE 'berta',
FLAG.
IF FLAG = SPACE.
DO 250 TIMES.
TAB_SRC−K = 'anton'. APPEND TAB_SRC.
5.19
Löschen eines Sets von Zeilen.
63
SAP_Tips
TAB_SRC−K = 'berta'. APPEND TAB_SRC.
TAB_SRC−K = 'carl '. APPEND TAB_SRC.
TAB_SRC−K = 'drago'. APPEND TAB_SRC.
ENDDO.
FLAG = 'X'.
ENDIF.
TAB_DEST[] = TAB_SRC[].
Tabelle TAB_DEST hat 1000 Sätze mit jeweils 500 Bytes, 250 entsprechen der WHERE Klausel.
DELETE TAB_DEST WHERE K = KVAL.
Bewertung
Mit der neuen DELETE Variante: DELETE itab [FROM ...] [TO ...] WHERE ... Wenn möglich sollte
WHERE mit FROM benutzt werden ... und/oder TO um mehr Performance zu bekommen. Die Performance
steigt mit DELETE itab WHERE ... anstatt LOOP AT itab WHERE ... DELETE itab. ENDLOOP. mit
der Anzahl der Einträge in der int. Tab.
*−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−
5.20
Bestimmte Tabelleneinträge zählen
Mit Feldtransport
DATA:
TAB1 LIKE VDARL OCCURS 0 WITH HEADER LINE.
SELECT
* FROM VDARL UP TO 200 ROWS INTO TABLE TAB1.
CLEAR: COUNT.
LOOP AT TAB1 WHERE SBEA = '07'.
COUNT = COUNT + 1.
ENDLOOP.
Ohne Feldtransport
DATA:
TAB1 LIKE VDARL OCCURS 0 WITH HEADER LINE.
5.20
Bestimmte Tabelleneinträge zählen
64
SAP_Tips
DATA: WA LIKE VDARL.
SELECT
* FROM VDARL UP TO 200 ROWS INTO TABLE TAB1.
CLEAR: COUNT.
LOOP AT TAB1 TRANSPORTING NO FIELDS WHERE SBEA = '07'.
COUNT = COUNT + 1.
ENDLOOP.
Bewertung
Int. Tab. enthält 200 Sätze mit der Satzlänge von VDARL. Falls die Tabelleninhalte nicht benötigt werden,
kann zum Zählen verschiedener Bedingungen aus einer int. Tab. der Zusatz TRANSPORTING NO FIELDS
den LOOP beschleunigen.
*−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−
5.21
Großen Datenbestand filtern
Die schnelle Indexsuche nutzen...
DATA:
TAB1 LIKE VDARL OCCURS 0 WITH HEADER LINE.
DATA: Z LIKE SY−TFILL.
SELECT
* FROM VDARL UP TO 800 ROWS INTO TABLE TAB1.
SORT TAB1 BY SBEA.
READ TABLE TAB1 WITH KEY SBEA = '07'.
LOOP AT TAB1 FROM SY−TABIX.
IF TAB1−SBEA NE '07'.
EXIT.
ENDIF.
ENDLOOP.
Mit klassischem LOOP
DATA:
TAB1 LIKE VDARL OCCURS 0 WITH HEADER LINE.
5.21
Großen Datenbestand filtern
65
SAP_Tips
SELECT
* FROM VDARL UP TO 800 ROWS INTO TABLE TAB1.
SORT TAB1 BY SBEA.
LOOP AT TAB1 WHERE SBEA = '07'.
ENDLOOP.
Bewertung
Voraussetzungen:
− Es soll nach einem 'Nicht−Key' Feld gesucht werden.
− Die interne Tabelle ist sortiert nach SBEA
− TAB1 enthält nur ausgewählte Felder nicht einen INCLUDE STRUCTURE.
− Falls die Tabelle nicht sortiert gehalten werden kann ist die
rechte Seite performanter.
*−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−
5.22
Geschachtelte Tab. oder EXTRACT
Verbundene interne Tabellen
IF Z1 = ' '.
DATA: BEGIN OF KOPF OCCURS 0,
NR1(5), DATEN1(10), DATEN2(10),
END OF KOPF.
DATA: BEGIN OF POSITIONEN OCCURS 0,
NR1(5), NR2(5), DATEN1(10), DATEN2(10),
END OF POSITIONEN.
KOPF−NR1 = '0'.
DO 100 TIMES.
KOPF−NR1 = KOPF−NR1 + 1.
POSITIONEN−NR1 = POSITIONEN−NR1 + 1.
5.22
Geschachtelte Tab. oder EXTRACT
66
SAP_Tips
KOPF−DATEN1 = 'TEST'.
APPEND KOPF.
POSITIONEN−NR2 = '0'.
DO 10 TIMES.
POSITIONEN−NR2 = POSITIONEN−NR2 + 1.
POSITIONEN−DATEN1 = 'TEST'.
APPEND POSITIONEN.
ENDDO.
ENDDO.
Z1 = '1'.
ENDIF.
LOOP AT KOPF.
LOOP AT POSITIONEN WHERE NR1 = KOPF−NR1.
ENDLOOP.
ENDLOOP.
Ein Extract
Muß global def. sein
*field−groups: header, kopf, positionen.
*data: nr1(5), nr2(5), k_daten1(10), k_daten2(10),
p_daten1(10), p_daten2(10).
*insert nr1 into header.
*insert k_daten1 k_daten2 into kopf.
*insert nr2 p_daten1 p_daten2 into positionen.
IF Z2 = ' '.
NR1 = '0'.
DO 100 TIMES.
5.22
Geschachtelte Tab. oder EXTRACT
67
SAP_Tips
NR1 = NR1 + 1.
K_DATEN1 = 'TEST'.
EXTRACT KOPF.
NR2 = '0'.
DO 10 TIMES.
NR2 = NR2 + 1.
P_DATEN1 = 'TEST'.
EXTRACT POSITIONEN.
ENDDO.
ENDDO.
Z2 = '1'.
ENDIF.
*extract
LOOP.
ENDLOOP.
Bewertung
*Voraussetzungen:
*− A C H T U N G: Dieses Bsp. kann nur 1x ausgeführt werden, da Field−Groups nur 1x pro Report
definiert werden dürfen (sonst DUMP).
Nur für Reports zu empfehlen nicht im Dialog verwenden.
*− Der fachliche Hintergrund ist in beiden Bsp. gleich. Es sollen Kopfdaten mit den zugehörigen
Positionsdaten bearbeitet werden. Beide Bsp. beinhalten die gleiche Datenmenge von
100 Kopfsätzen mit jeweils 10 Positionen.
*− Noch extremer ist der Performancegewinn bei weiteren Schachtelungen.
*−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−
5.22
Geschachtelte Tab. oder EXTRACT
68
SAP_Tips
5.23
Anzahl Tabelleneinträge ermitteln
Zu Fuß: Zählen...
DATA: BEGIN OF ITAB OCCURS 0,
TEXT(5), ZAHL1 TYPE P, ZAHL2 TYPE P,
END OF ITAB.
CLEAR COUNT.
ITAB−TEXT = 'Test'.
REFRESH ITAB.
DO 1000 TIMES.
APPEND ITAB.
ENDDO.
LOOP AT ITAB.
COUNT = COUNT + 1.
ENDLOOP.
Lassen wir den Kernel arbeiten...
DATA: BEGIN OF ITAB OCCURS 0,
TEXT(5), ZAHL1 TYPE P, ZAHL2 TYPE P,
END OF ITAB.
ITAB−TEXT = 'Test'.
REFRESH ITAB.
DO 1000 TIMES.
APPEND ITAB.
ENDDO.
DESCRIBE TABLE ITAB LINES SY−TFILL.
Bewertung
5.23
Anzahl Tabelleneinträge ermitteln
69
SAP_Tips
Die int. Tab. hat 1000 Einträge. Zum Auszählen von internen Tabellen (ohne Bedingung) ist describe Pflicht.
5.24
Tabelle vom Typ SORTED (4.0)
Key−Zugriff auf Standard−ITAB
DATA: ITAB LIKE VDARL OCCURS 0 WITH HEADER LINE..
SELECT
* FROM VDARL INTO TABLE ITAB
WHERE BUKRS
= '0020'
AND
SARCHIV
=''
AND
RANL BETWEEN '0002000000010' AND
'0002000600000'.
READ TABLE ITAB WITH KEY
MANDT = SY−MANDT
BUKRS = '0020'
SARCHIV = ' '
RANL
= '0002000500010'.
Key Zugriff auf SORTED−ITAB
DATA: STAB LIKE SORTED TABLE OF VDARL
WITH UNIQUE KEY MANDT BUKRS SARCHIV RANL
WITH HEADER LINE.
SELECT
* FROM VDARL INTO TABLE STAB
WHERE BUKRS
= '0020'
AND
SARCHIV
=''
AND
RANL BETWEEN '0002000000010' AND
'0002000600000'.
READ TABLE STAB WITH TABLE KEY
MANDT = SY−MANDT
5.24
Tabelle vom Typ SORTED (4.0)
70
SAP_Tips
BUKRS = '0020'
SARCHIV = ' '
RANL
= '0002000500010'.
Bewertung
Es gibt drei unterschiedliche Typen von internen Tabellen: Standardtabelle, sortierte Tabelle und
Hash−Tabelle.
·
In einer Standardtabelle greifen Sie auf Datensätze entweder über den Tabellenindex oder den
Schlüssel zu. Wenn Sie den Schlüssel verwenden, steht die Antwortzeit in linearer Abhängigkeit zur Anzahl
der Tabelleneinträge. Der Schlüssel einer Standardtabelle ist immer NON−UNIQUE.
·
In einer sortierten Tabelle werden die Einträge immer nach dem Schlüssel in absteigender
Reihenfolge sortiert gespeichert. Sie können auf Datensätze entweder über den Tabellenindex oder über den
Schlüssel zugreifen. Wenn Sie den Schlüssel verwenden, steht die Antwortzeit in logarithmischer
Abhängigkeit zur Anzahl der Tabelleneinträge, da das System die binäre Suche verwendet. Der Schlüssel
einer sortierten Tabelle kann entweder UNIQUE oder NON−UNIQUE sein. * Füllen Sie sortierte Tabellen
nicht über Indexoperationen (INSERT wa INTO tab1 INDEX tabix, APPEND tab1 FROM wa), da dies die
Sortierreihenfolge durcheinanderbringen kann. Eine sortierte Tabelle kann nicht neu sortiert werden. Der
Versuch, eine sortierte Tabelle zu sortieren, führt zu einer Syntaxprüfung im ABAP Editor. *Schlüsselzugriff
können Sie bei jedem Tabellentyp verwenden. Jedoch ist die Performance dieser Operationen für jeden
Tabellentyp anders (O(n), O(log(n), O(1)). INSERT mit Index oder APPEND sind gefährlich in sortierten
Tabellen, da sie leicht die Sortierreihenfolge durcheinanderbringen könen. Aus syntaktischen Gründen sind
sie in Hash−Tabellen nicht zulässig.
5.25
Tabelle vom Typ HASHED (4.0)
Key−Zugriff auf Standard−ITAB
Key−Zugriff auf Standard−ITAB
DATA: ITAB LIKE VDARL OCCURS 0 WITH HEADER LINE..
SELECT
* FROM VDARL INTO TABLE ITAB
WHERE BUKRS
= '0020'
AND
SARCHIV
=''
AND
RANL BETWEEN '0002000000010' AND
'0002000600000'.
READ TABLE ITAB WITH KEY
MANDT = SY−MANDT
5.25
Tabelle vom Typ HASHED (4.0)
71
SAP_Tips
BUKRS = '0020'
SARCHIV = ' '
RANL
= '0002000500010'.
Key Zugriff auf HASHED−ITAB
DATA: HTAB LIKE HASHED TABLE OF VDARL
WITH UNIQUE KEY MANDT BUKRS SARCHIV RANL
WITH HEADER LINE.
SELECT
* FROM VDARL INTO TABLE HTAB
WHERE BUKRS
= '0020'
AND
SARCHIV
=''
AND
RANL BETWEEN '0002000000010' AND
'0002000600000'.
READ TABLE HTAB WITH TABLE KEY
MANDT = SY−MANDT
BUKRS = '0020'
SARCHIV = ' '
RANL
= '0002000500010'.
Bewertung
Es gibt drei unterschiedliche Typen von internen Tabellen: Standardtabelle, sortierteTabelle und
Hash−Tabelle.
·
In einer Standardtabelle greifen Sie auf Datensätze entweder über den Tabellenindex oder den
Schlüssel zu. Wenn Sie den Schlüssel verwenden, steht die Antwortzeit in linearer Abhängigkeit zur Anzahl
der Tabelleneinträge. Der Schlüssel einer Standardtabelle ist immer NON−UNIQUE.
·
Auf Hash−Tabellen können Sie NUR über ihren Schlüssel zugreifen. Die Antwortzeit ist
konstant und hängt NICHT von der Anzahl der Tabelleneinträge ab, da das System einen Hash−Algorithmus
verwendet, um auf Einträge zuzugreifen. Der Schlüssel einer Hash−Tabelle muß immer UNIQUE sein. *
Beachten Sie, daß Sie bei Hash−Tabellen keine Indexoperationen (APPEND, INSERT .. INDEX)
durchführen können. Interne Hash−Tabellen lassen sich gut zum Speichern oft gelesener Stammdaten
verwenden, da so wiederholte Datenbankzugriffe vermieden werden.
5.25
Tabelle vom Typ HASHED (4.0)
72
SAP_Tips
Schlüsselzugriff können Sie bei jedem Tabellentyp verwenden. Jedoch ist die Performance dieser
Operationen für jeden Tabellentyp anders (O(n), O(log(n), O(1)).
Ein INSERT mit Schlüssel in einer Standard− oder Hash−Tabelle hat denselben Effekt wie eine
APPEND−Anweisung. Mit Hash−Tabellen können Sie keine Indexoperationen (APPEND, INSERT ..
Hash−Tabellen sinnvoll.
**−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−
5.25
Tabelle vom Typ HASHED (4.0)
73
6
String manipulation
6.1
Spezielle Operatoren im IF (CA, ...)
DO−Loop mit Field−Symbols
ASSIGN CHA(1) TO <C>.
DO 200 TIMES.
IF <C> = '(' OR <C> = ')'.
"...Verarbeitung
EXIT.
ENDIF.
ASSIGN <C>+1 TO <C>.
ENDDO.
Using the CA operator
IF CHA(200) CA '()'.
"...Verarbeitung
ENDIF.
Bewertung
Die Nutzung der speziellen Operators CO, CA, CS ist wesentlich performanter als ein DO−Loop mit
Feld−Symbolen.
6.2
String Verknüpfung
Nutzung einer Verknüpfungs−FBS
CALL FUNCTION 'STRING_CONCATENATE_3'
EXPORTING
STRING1 = T100−ARBGB
STRING2 = T100−MSGNR
6
String manipulation
74
SAP_Tips
STRING3 = T100−TEXT
IMPORTING
STRING
= CLA
EXCEPTIONS
TOO_SMALL = 01.
Nutzung des CONCATENATE statement
CONCATENATE T100−ARBGB
T100−MSGNR
T100−TEXT INTO CLA.
Bewertung
Einige FBS zur String−Manipulation sollten nicht mehr verwendet werden. Bitte ersetzen durch ABAP/4
statements oder Functioen:
STRING_CONCATENATE... −> CONCATENATE,
STRING_SPLIT... −> SPLIT,
STRING_LENGTH −> strlen(),
STRING_CENTER −> WRITE...TO...CENTERED,
STRING_MOVE_RIGHT −> WRITE...TO...RIGHT−JUSTIFIED,
6.3
String Verknüpfung II
Notwendiger Vorlauf für Beispiel
Programmiert
MOVE 'Jane' TO CMA.
MOVE 'Miller' TO CMB.
MOVE 'New York City' TO CMC.
I1 = STRLEN( CMA ). I2 = STRLEN( CMB ).
MOVE 'Mrs. ' TO CHA.
MOVE CMA
6.3
TO CHA+5. I1 = I1 + 6.
String Verknüpfung II
75
SAP_Tips
MOVE CMB
TO CHA+I1. I1 = I1 + I2 + 1.
MOVE 'from ' TO CHA+I1. I1 = I1 + 5.
MOVE CMC
TO CHA+I1.
"Mrs. Jane Miller from New York City" is the final value of CHA.
Nutzung des CONCATENATE statement
MOVE 'Jane' TO CMA.
MOVE 'Miller' TO CMB.
MOVE 'New York City' TO CMC.
CONCATENATE
'Mrs.' CMA CMB 'from' CMC INTO CHA
SEPARATED BY SPACE.
"Mrs. Jane Miller from New York City" is the final value of CHA.
Bewertung
Hier ist die Nutzung des CONCATENATE statement Pflicht !
6.4
Trennen von Textstrings
Nutzung SEARCH und MOVE mit Offset
DATA: AREA_CODE(20), TEL_NO1(20), TEL_NO2(20).
MOVE '(410)−45174−66354312' TO CMA.
"CMA contains '(410)−45174−66354312' and shall be
"split into AREA_CODE,
"
TEL_NO1,
"
TEL_NO2.
SEARCH CMA FOR '−'.
MOVE CMA(SY−FDPOS) TO AREA_CODE.
I1 = SY−FDPOS + 2.
6.4
Trennen von Textstrings
76
SAP_Tips
SEARCH CMA FOR '−' STARTING AT I1.
I1 = I1 − 1.
MOVE CMA+I1(SY−FDPOS) TO TEL_NO1.
I1 = I1 + SY−FDPOS + 1.
MOVE CMA+I1 TO TEL_NO2.
Nutzung SPLIT statement
DATA: AREA_CODE(20), TEL_NO1(20), TEL_NO2(20).
MOVE '(410)−45174−66354312' TO CMA.
"CMA contains '(410)−45174−66354312' and shall be
"splitted into AREA_CODE,
"
TEL_NO1,
"
TEL_NO2.
SPLIT CMA AT '−' INTO AREA_CODE
TEL_NO1
TEL_NO2.
Bewertung
Die Nutzung des SPLIT−statements ist performanter
*
6.5
Löschen führender Leerstellen
Shifting by SY−FDPOS places.
" CLA contains the string
"'
"Editor line n'.
IF CLA CN SPACE. ENDIF.
SHIFT CLA BY SY−FDPOS PLACES LEFT.
SHIFT...LEFT DELETING LEADING...
6.5
Löschen führender Leerstellen
77
SAP_Tips
" CLA contains the string
"'
"Editor line n'.
SHIFT CLA LEFT DELETING LEADING SPACE.
Bewertung
Die Nutzung von SHIFT...LEFT DELETING LEADING... ist hier vorzuziehen!
*
Andere Konstructioen (mit CN und SHIFT...BY SY−FDPOS PLACES, mit CONDENSE −falls möglich−,
mit CN und ASSIGN CLA+SY−FDPOS(LEN) ...) benötigen mehr Zeit. Niemals: SHIFT innerhalb
WHILE−loop!
6.6
Nutzung strlen()
Bestimmen Kontrollsumme über Feldlänge
DATA: BEGIN OF STR, LINE TYPE X, END OF STR,
CHECK_SUM TYPE I.
MOVE 'KALEBVPQDSCFG' TO CLA.
"DATA: BEGIN OF STR, LINE TYPE X, END OF STR,
"
CHECK_SUM TYPE I.
"MOVE 'KALEBVPQDSCFG' TO CLA.
DO 64 TIMES VARYING STR FROM CLA NEXT CLA+1.
CHECK STR NE SPACE.
ADD STR−LINE TO CHECK_SUM.
ENDDO.
Bestimmen Kontrollsumme über strlen()
DATA: BEGIN OF STR, LINE TYPE X, END OF STR,
CHECK_SUM TYPE I.
MOVE 'KALEBVPQDSCFG' TO CLA.
"DATA: BEGIN OF STR, LINE TYPE X, END OF STR,
6.6
Nutzung strlen()
78
SAP_Tips
"
CHECK_SUM TYPE I.
"MOVE 'KALEBVPQDSCFG' TO CLA.
I1 = STRLEN( CLA ).
DO I1 TIMES VARYING STR FROM CLA NEXT CLA+1.
CHECK STR NE SPACE.
ADD STR−LINE TO CHECK_SUM.
ENDDO.
Bewertung
Nutzen Sie die strlen( )−Funktion zur Einschränkung des DO Loops auf relvante Teile eines Feldes. Hier:
Bestimmung einer Kontrollsumme
6.7
Initialisierung
Initializing strings: CLEAR/TRANSLATE vs. CLEAR WITH val
Initialisierung mit CLEAR/TRANSLATE
DATA STRING(255).
STRING is a 255 byte character field
CLEAR STRING.
TRANSLATE STRING USING ' *'.
Notwendiger Vorlauf für Beispiel
DATA STRING(255).
Initialisierung mit CLEAR WITH val
STRING is a 255 byte character field
CLEAR STRING WITH '*'.
Bewertung
"CLEAR f WITH val" muss immer genutzt werden, wenn ein Feld mit Werten ungleich des Inital−Wertes
belegt werden soll!
6.7
Initialisierung
79
7
Typisierung
7.1
Typisierte vs. nicht typ. Parameter
Nicht typisierte Parameter
DATA: M6 LIKE T006,
IX TYPE I VALUE 10.
PERFORM UP1 USING IX M6−DIMID M6−ZAEHL M6−ISOCODE M6−ANDEC M6−PRIMARY.
FORM UP1 USING
REPEAT
DIMID
ZAEHL
ISOCODE
ANDEC
PRIMARY.
Identischer Code links und rechts:
DO REPEAT TIMES.
T006−DIMID = DIMID.
T006−ZAEHL = ZAEHL.
T006−ISOCODE = ISOCODE.
T006−ANDEC = ANDEC.
T006−PRIMARY = PRIMARY.
I1
= REPEAT − SY−INDEX.
ENDDO.
ENDFORM.
Typisierte Parameter
7
Typisierung
80
SAP_Tips
DATA: M6 LIKE T006,
IX TYPE I VALUE 10.
PERFORM UP2 USING IX M6−DIMID M6−ZAEHL M6−ISOCODE M6−ANDEC M6−PRIMARY.
FORM UP2 USING
REPEAT TYPE I
DIMID
LIKE T006−DIMID
ZAEHL
LIKE T006−ZAEHL
ISOCODE LIKE T006−ISOCODE
ANDEC
LIKE T006−ANDEC
PRIMARY LIKE T006−PRIMARY.
Identischer Code links und rechts:
DO REPEAT TIMES.
T006−DIMID = DIMID.
T006−ZAEHL = ZAEHL.
T006−ISOCODE = ISOCODE.
T006−ANDEC = ANDEC.
T006−PRIMARY = PRIMARY.
I1
= REPEAT − SY−INDEX.
ENDDO.
ENDFORM.
Bewertung
Wenn man die Formalparameter durch Typen spezifiziert, kann der ABAP/4−Compiler das Programm
vorzeitig optimieren. Zusätzlich vermeidet man eine ungewollte Übergabe von falschen Parametern an die
FORM−Routine. Wenn man große, nicht typisierte Programme hat, kann man das Typisierungstool in der
Development Worbench nutzen: Aufruf Report RSPARM30 oder SE38 −> Hilfsmittel −> Typisierung
7
Typisierung
81
SAP_Tips
7.2
Typisierte vs. nicht typ. Feldsymbole
Feldsymbol ohne Type
FIELD−SYMBOLS: <F>.
ASSIGN I1 TO <F>.
I2 = <F>.
I3 = <F>.
I4 = <F>.
Typisierte Feldsymbole
FIELD−SYMBOLS: <I> TYPE I.
ASSIGN I1 TO <I>.
I2 = <I>.
I3 = <I>.
I4 = <I>.
Bewertung
Wenn man die Field−Symbols durch Typen spezifiziert, kann der ABAP/4−Compiler das Programm
vorzeitig optimieren.
7.2
Typisierte vs. nicht typ. Feldsymbole
82
8
If, Case, ....(Performance und Wartbarkeit)
8.1
If vs. Case
If
IF
C1A = 'A'. WRITE '1'.
ELSEIF C1A = 'B'. WRITE '2'.
ELSEIF C1A = 'C'. WRITE '3'.
ELSEIF C1A = 'D'. WRITE '4'.
ELSEIF C1A = 'E'. WRITE '5'.
ELSEIF C1A = 'F'. WRITE '6'.
ELSEIF C1A = 'G'. WRITE '7'.
ELSEIF C1A = 'H'. WRITE '8'.
ENDIF.
Case
CASE C1A.
WHEN 'A'. WRITE '1'.
WHEN 'B'. WRITE '2'.
WHEN 'C'. WRITE '3'.
WHEN 'D'. WRITE '4'.
WHEN 'E'. WRITE '5'.
WHEN 'F'. WRITE '6'.
WHEN 'G'. WRITE '7'.
WHEN 'H'. WRITE '8'.
ENDCASE.
Bewertung
8
If, Case, ....(Performance und Wartbarkeit)
83
SAP_Tips
Das CASE−Statement ist übersichtlicher und sollte daher verwendet
werden (WARTBARKEIT) !
CASE ist nur wenig schneller als eine IF..ELSEIf−Konstruktion.
8.2
While vs. Do
DO
I1 = 0.
DO.
IF C1A NE SPACE. EXIT. ENDIF.
ADD 1 TO I1.
IF I1 GT 10. C1A = 'X'. ENDIF.
ENDDO.
Case
I1 = 0.
WHILE C1A = SPACE.
ADD 1 TO I1.
IF I1 GT 10. C1A = 'X'. ENDIF.
ENDWHILE.
Bewertung
Nutzen Sie WHILE anstelle von DO+EXIT−Konstruktionen − falls möglich−. WHILE ist übersichtlicher und
etwas schneller. (WARTBARKEIT)
8.3
Case vs. Perform i Of ...
I1 = 5.
Case
(I1 = 5 in this test)
CASE I1.
8.2
While vs. Do
84
SAP_Tips
WHEN 1. PERFORM PV1.
WHEN 2. PERFORM PV2.
WHEN 3. PERFORM PV3.
WHEN 4. PERFORM PV4.
WHEN 5. PERFORM PV5.
WHEN 6. PERFORM PV6.
WHEN 7. PERFORM PV7.
WHEN 8. PERFORM PV8.
ENDCASE.
I1 = 5.
Perform i Of ...
(I1 = 5 in this test)
PERFORM I1 OF
PV1
PV2
PV3
PV4
PV5
PV6
PV7
PV8.
Bewertung
perform i of ist zwar schneller aber weniger übersichtlich.
Beachte: I1 muß fortlaufen belegt werden (1 bis n) Wg. Wartbarkeit nicht verwenden
8.2
While vs. Do
85
9
Field Conversion
9.1
Field Types I and P
Type P
DATA: IP TYPE P.
DO 5 TIMES.
IP = SY−INDEX * 2.
READ TABLE X100 INDEX IP.
ENDDO.
Type I
DATA: IP TYPE I.
DO 5 TIMES.
IP = SY−INDEX * 2.
READ TABLE X100 INDEX IP.
ENDDO.
Bewertung
Nutzen Sie Datentyp I für typische Integer−Variablen − z.B. Indizes , Zähler
9.2
Literals Type C and Type I
Type C
SY−SUBRC = '0'.
CASE SY−SUBRC.
WHEN '1'.
WHEN '2'.
WHEN '3'.
WHEN '4'.
9
Field Conversion
86
SAP_Tips
ENDCASE.
Type I
SY−SUBRC = 0.
CASE SY−SUBRC.
WHEN 1.
WHEN 2.
WHEN 3.
WHEN 4.
ENDCASE.
Bewertung
Nutzen Sie numerische Literale oder Konstanten vom Datentyp I anstelle von Character−strings, wenn Sie
Felder vom Typ I Integer−Typ P vergleichen oder diesen zuweisen.
9.3
Konstanten vom Typ F
Zuweisung Literal
DATA:
FLOAT TYPE F.
FLOAT = '3.1415926535897932'.
Constant Type F
CONSTANTS:
PI TYPE F VALUE '3.1415926535897932'.
DATA:
FLOAT TYPE F.
FLOAT = PI.
Bewertung
Konstanten werden bei Definition angegeben (constants) !
9.3
Konstanten vom Typ F
87
SAP_Tips
9.4
Berechnungen
Type N
DATA:
N1(15) TYPE N VALUE '123456789012345',
N2(15) TYPE N VALUE '543210987654321',
N3(15) TYPE N.
N3 = N1 + N2.
Type P
DATA:
P1
TYPE P VALUE '123456789012345',
P2
TYPE P VALUE '543210987654321',
P3
TYPE P.
P3 = P1 + P2.
Bewertung
Use number types for arithmetic
9.5
Gemischte Datentypen
Several Types
DATA: F1 TYPE I VALUE 2,
F2 TYPE P DECIMALS 2 VALUE '3.14',
F3 TYPE F.
F3 = F1 * F2.
Only One Type
DATA: F1 TYPE F VALUE 2,
F2 TYPE F
VALUE '3.14',
F3 TYPE F.
9.4
Berechnungen
88
SAP_Tips
F3 = F1 * F2.
Bewertung
Verwenden Sie in arithmetischen Operationen immer identische Datentypen !
−> Nur in wirklich begründeten Fällen davon abweichen.
[Home] [SAP Tips ] [Forum]
9.4
Berechnungen
89
Herunterladen