Tabellenzugriff mit OpenSQL (ABAP): Unterschied zwischen den Versionen

Aus MattWiki
Keine Bearbeitungszusammenfassung
 
(9 dazwischenliegende Versionen desselben Benutzers werden nicht angezeigt)
Zeile 1: Zeile 1:
Dieser Artikel beschäftigt sich mit Anleitungen, wie auf Datenbanken mit hilfe von ABAP in SAP Open SQL zugegriffen werden kann.
Dieser Artikel zeigt, wie auf Dictionary-Tabellen in der Datenbank mit Hilfe von ABAP und SAP Open SQL zugegriffen werden kann.


Dabei bietet Open SQL mit einem einheitlichen Befehlssatz die Möglichkeit, auf verschiedene zugrundeliegende Datenbanksysteme zuzugreifen.
Dabei bietet Open SQL mit einem einheitlichen Befehlssatz die Möglichkeit, auf verschiedene zugrundeliegende Datenbanksysteme zuzugreifen.
Zeile 5: Zeile 5:
= Einzelnen Datensatz in eine Struktur lesen =
= Einzelnen Datensatz in eine Struktur lesen =


= Loop mit SELECT über Tabelle =
= SELECT - ENDSELECT - Loop mit SELECT über Tabelle =
(Inperformant)
<syntaxhighlight lang="abap">
SELECT * FROM dbtab INTO ls_tab
  " Line 1
  " Line 2
  " Line 3
ENDSELECT.
</syntaxhighlight>
 
Die SELECT-ENDSELECT-Kontrollstruktur sollte nicht mehr verwendet werden, weil der ABAP-Prozessor dabei jeden Datensatz einzeln vom Datenbankserver holt, und man damit unnötig teuer Daten vom Datenbankserver holt bzw. ihn unnötig mit kleinkram beschäftigt.


= Datenbanktabelle in interne Tabelle laden =
= SELECT - Datenbanktabelle in interne Tabelle laden =
 
=== Allgmeine Syntax ===
<syntaxhighlight lang="abap">
<syntaxhighlight lang="abap">
SELECT  
SELECT field1 field2 field3
  field1
  field2
  field3
   FROM <dbtab>  
   FROM <dbtab>  
   WHERE field1 = 'abc'
  INTO CORRESPONDING FIELDS OF TABLE <itab>
   INTO CORRESPONDING FIELDS OF TABLE <itab>.
   WHERE field1 = 'abc'.
</syntaxhighlight>
 
<syntaxhighlight lang="abap">
SELECT plant customer doc_number /bic/matnr1 quantity amount
  FROM /bic/aznwvkdat00
   INTO CORRESPONDING FIELDS OF TABLE lt_vkdat
  WHERE plant = '1060'.
</syntaxhighlight>
 
Dabei ermöglicht <code>INTO CORRESPONDING FIELDS OF TABLE</code> es, die Daten aus einer Datenbanktabelle in eine interne Tabelle zu schreiben, die nur eine Teilmenge der Felder enthält. Das Matching findet anhand der Feldnamen statt.
 
=== Mit SELECT-OPTIONS / RRRANGE-Tabelle ===
 
<syntaxhighlight lang="abap">
" Build filter table containing search values
 
ls_range-sign = 'I'.
ls_range-opt = 'EQ'.
ls_range-high = ''.
 
LOOP AT itab ASSIGNING <itab>.
  ls_range-low = <itab>-field1.
  APPEND ls_range TO lt_range.
ENDLOOP.
 
" Find desired existing target LR_PROJ and store in table
SELECT field1, field2, field3
  FROM ztesttab
  INTO CORRESPONDING FIELDS OF TABLE @lt_temp_tab
  WHERE objvers = 'A'
    AND zkeyfield1 IN @lt_range.  
</syntaxhighlight>
</syntaxhighlight>


= Datensätze erstellen =
Evtl. Range-Tabelle um Duplikate bereinigen mit <code>DELETE ADJACENT DUPLICATES FROM lt_rangetab</code>.
 
= INSERT - Datensätze erstellen =
<syntaxhighlight lang="abap">
<syntaxhighlight lang="abap">
INSERT INTO <dbtab> VALUES <wa>.
INSERT INTO <dbtab> VALUES <wa>.
Zeile 28: Zeile 68:
</syntaxhighlight>
</syntaxhighlight>


= Datensätze aktualisieren =
= UPDATE - Datensätze ändern =
<syntaxhighlight lang="abap">
<syntaxhighlight lang="abap">
UPDATE <dbtab> FROM <wa>.
UPDATE <dbtab> FROM <wa>.
Zeile 35: Zeile 75:
</syntaxhighlight>
</syntaxhighlight>


= Datensätze löschen =
UPDATE wird direkt auf dem Datenbankserver ausgeführt. Kann mehrere Datensätze auf einmal verändern.
 
Möchte man eine Vielzahl Datensätze jeweils unterschiedlich bearbeiten, müsste man den UPDATE-Befehl mehrmals mit unterschiedlichen WHERE-Klauseln aufrufen. Dazu wäre ein übergeordneter LOOP notwendig. Dies wäre allerdings wenig performant. Für so eine Operation würde man eher alle Inhalte in einer internen Tabelle vorbereiten und dann in einem Schritt mit MODIFY in die Datenbank schreiben.
 
Es können auch mehrere Datensätze direkt geändert werden:
 
<syntaxhighlight lang="abap">
UPDATE <dbtab>
  SET col1 = 'X'
  WHERE col2 = 'VAL2' OR col2 LIKE 'VAL3-%'.
</syntaxhighlight>
 
= DELETE - Datensätze löschen =
<syntaxhighlight lang="abap">
<syntaxhighlight lang="abap">
DELETE FROM <dbtab> WHERE <cond>.
DELETE FROM <dbtab> WHERE <cond>.
DELETE FROM <dbtab> FOR ALL ENTRIES IN <itab> WHERE <field1> = <itab>-<field1>. " Ungetestet


DELETE <dbtab> FROM <wa>.
DELETE <dbtab> FROM <wa>.


DELETE <dbtab> FROM TABLE <itab>.
DELETE <dbtab> FROM TABLE <itab>.
</syntaxhighlight>
</syntaxhighlight>
Quellen:
ABAP Programming (BC-ABA) / Deleting Lines: https://help.sap.com/viewer/cfae740a0a21455dbe6e510c2d86e36a/7.31.18/en-US/fceb3aef358411d1829f0000e829fbfe.html
ABAP Programming (BC-ABA) / Selecting Rows: https://help.sap.com/viewer/cfae740a0a21455dbe6e510c2d86e36a/7.31.18/en-US/fceb3a1f358411d1829f0000e829fbfe.html
[[Category:ABAP]]
[[Category:ABAP]]

Aktuelle Version vom 8. April 2020, 16:07 Uhr

Dieser Artikel zeigt, wie auf Dictionary-Tabellen in der Datenbank mit Hilfe von ABAP und SAP Open SQL zugegriffen werden kann.

Dabei bietet Open SQL mit einem einheitlichen Befehlssatz die Möglichkeit, auf verschiedene zugrundeliegende Datenbanksysteme zuzugreifen.

Einzelnen Datensatz in eine Struktur lesen

SELECT - ENDSELECT - Loop mit SELECT über Tabelle

SELECT * FROM dbtab INTO ls_tab
  " Line 1
  " Line 2
  " Line 3
ENDSELECT.

Die SELECT-ENDSELECT-Kontrollstruktur sollte nicht mehr verwendet werden, weil der ABAP-Prozessor dabei jeden Datensatz einzeln vom Datenbankserver holt, und man damit unnötig teuer Daten vom Datenbankserver holt bzw. ihn unnötig mit kleinkram beschäftigt.

SELECT - Datenbanktabelle in interne Tabelle laden

Allgmeine Syntax

SELECT field1 field2 field3
  FROM <dbtab> 
  INTO CORRESPONDING FIELDS OF TABLE <itab>
  WHERE field1 = 'abc'.
SELECT plant customer doc_number /bic/matnr1 quantity amount
  FROM /bic/aznwvkdat00
  INTO CORRESPONDING FIELDS OF TABLE lt_vkdat
  WHERE plant = '1060'.

Dabei ermöglicht INTO CORRESPONDING FIELDS OF TABLE es, die Daten aus einer Datenbanktabelle in eine interne Tabelle zu schreiben, die nur eine Teilmenge der Felder enthält. Das Matching findet anhand der Feldnamen statt.

Mit SELECT-OPTIONS / RRRANGE-Tabelle

" Build filter table containing search values

ls_range-sign = 'I'.
ls_range-opt = 'EQ'.
ls_range-high = ''.

LOOP AT itab ASSIGNING <itab>.
  ls_range-low = <itab>-field1.
  APPEND ls_range TO lt_range.
ENDLOOP.

" Find desired existing target LR_PROJ and store in table
SELECT field1, field2, field3
  FROM ztesttab
  INTO CORRESPONDING FIELDS OF TABLE @lt_temp_tab
  WHERE objvers = 'A'
    AND zkeyfield1 IN @lt_range.

Evtl. Range-Tabelle um Duplikate bereinigen mit DELETE ADJACENT DUPLICATES FROM lt_rangetab.

INSERT - Datensätze erstellen

INSERT INTO <dbtab> VALUES <wa>.

INSERT <dbtab> FROM <wa>.

INSERT <dbtab> FROM TABLE <itab>.

UPDATE - Datensätze ändern

UPDATE <dbtab> FROM <wa>.

UPDATE <dbtab> FROM TABLE <itab>.

UPDATE wird direkt auf dem Datenbankserver ausgeführt. Kann mehrere Datensätze auf einmal verändern.

Möchte man eine Vielzahl Datensätze jeweils unterschiedlich bearbeiten, müsste man den UPDATE-Befehl mehrmals mit unterschiedlichen WHERE-Klauseln aufrufen. Dazu wäre ein übergeordneter LOOP notwendig. Dies wäre allerdings wenig performant. Für so eine Operation würde man eher alle Inhalte in einer internen Tabelle vorbereiten und dann in einem Schritt mit MODIFY in die Datenbank schreiben.

Es können auch mehrere Datensätze direkt geändert werden:

UPDATE <dbtab>
  SET col1 = 'X'
  WHERE col2 = 'VAL2' OR col2 LIKE 'VAL3-%'.

DELETE - Datensätze löschen

DELETE FROM <dbtab> WHERE <cond>.

DELETE FROM <dbtab> FOR ALL ENTRIES IN <itab> WHERE <field1> = <itab>-<field1>. " Ungetestet

DELETE <dbtab> FROM <wa>.

DELETE <dbtab> FROM TABLE <itab>.

Quellen:

ABAP Programming (BC-ABA) / Deleting Lines: https://help.sap.com/viewer/cfae740a0a21455dbe6e510c2d86e36a/7.31.18/en-US/fceb3aef358411d1829f0000e829fbfe.html

ABAP Programming (BC-ABA) / Selecting Rows: https://help.sap.com/viewer/cfae740a0a21455dbe6e510c2d86e36a/7.31.18/en-US/fceb3a1f358411d1829f0000e829fbfe.html