Exception statt sy-subrc

Die Objektorientierung mit ABAP®: Vererbung, Dynamische Programmierung, GUI Controls (u.a. ALV im OO).
18 Beiträge • Seite 1 von 2 (current) Nächste
18 Beiträge Seite 1 von 2 (current) Nächste

Exception statt sy-subrc

Beitrag von msfox (Specialist / 364 / 56 / 74 ) »
Es gibt bei uns gerade eine Diskussion unter den Entwickler, was richtig ist.

Geht hier nur ums Prinzip. Ich musste das etwas "schwärzen" und hoffe, es ist noch erkennbar.
Bisher:

Code: Alles auswählen.

READ TABLE lt_xxxx WITH KEY lfnum = ls_xxxxx-aaaaa INTO DATA(ls_ccccc).      
IF sy-subrc <> 0.        
    RAISE EXCEPTION TYPE ...     
ELSE.        
   ls_xxxxx-aaaa = ls_ccccc-xxxx.      
ENDIF.
Neu:

Code: Alles auswählen.

TRY.          
   ls_xxxx-aaaaa = lt_xxxx[ lfnum = ls_xxxx-aaaaa ]-xxxx.        
CATCH cx_sy_itab_line_not_found.         
   RAISE EXCEPTION TYPE ...      
ENDTRY.
Ich kenne das noch aus meinen Programmieranfängen in JAVA, dass man Dinge prüft und nicht einfach auf eine Exception laufen lässt. Also etwas auf "Gut Glück" ändern will, was aber nicht geht. Es gab dafür auch einen Begriff in der Programmierwelt. Zuminstest in Java war damals eine sauber Prüfung effizienter als ein Exception-Handling.
--
Wie macht ihr das bzw. was ist der bessere Stiel?

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


Re: Exception statt sy-subrc

Beitrag von DeathAndPain (Top Expert / 1939 / 257 / 412 ) »
Eine Exception - gerade eine klassenbasierte - kostet eine ganze Stange Performance. Das ist egal, wenn es wirklich ein Ausnahmefall ist, der nur alle Jubeljahre mal auftritt. Allerdings willst Du in Deinem Beispiel ja tatsächlich (so oder so) eine Exception werfen. Ich meine, dass es Standpunkt der SAP ist, dass man dann modernerweise klassenbasiert mit TRY...CATCH vorgehen soll.

ich würde das aber nicht machen, wenn Du auf das Nichtvorhandensein der Zeile selber reagieren und gar keine Exception werfen willst.

Allerdings missfällt mir bei Deiner ersten Version die Verwendung des hässlichen ollen READ TABLE. Ich würde da einen ASSIGN INTO feldsymbol machen. Ist performanter und setzt auch den SY-SUBRC, wenn es die Zeile nicht gibt. Zugleich ist sie kosmetisch auch schöner. Im übrigen würde ich den Ausgang, den ich für wahrscheinlicher halte (also dass es die Zeile gibt), als Erstes nennen, jedenfalls wenn beide Teile des IF-Blocks nur solche Einzeiler sind. Also:

Code: Alles auswählen.

ASSIGN lt_xxxx[ lfnum = ls_xxxx-aaaaa ] TO FIELD-SYMBOL(<ccccc>).
IF sy-subrc = 0.
  ls_xxxxx-aaaa = <ccccc>.
ELSE.
  RAISE EXCEPTION TYPE ...
ENDIF.

Re: Exception statt sy-subrc

Beitrag von msfox (Specialist / 364 / 56 / 74 ) »
Das Beispiel stammte noch aus alten Quellcode, der erst einmal so in eine neue Welt übernommen wurde. Da der Code schlecht lesbar und nur bedingt dokumentiert ist, wurde bestimmte Teile erst einmal so belassen. Also auch das READ TABLE.
--
Wenn ich ein ASSIGN mache und es die Zeile nicht gibt, dann wird wohl keine cx_sy_itab_line_not_found geworfen?
--
Dein Beispiel würde vermutlich andere Diskussionen hervorrufen. Es soll alles funktionsorientiert programmiert werden. Für mein Verständnis steht dafür der Zielwert immer links vom = und der Quellwert rechts. Das wäre bei einem ASSIGN nicht so. Darum wird auch überall von MOVE-CORRESPONDING auf xyz = CORRESPONDING umgestellt.

Re: Exception statt sy-subrc

Beitrag von black_adept (Top Expert / 4087 / 126 / 940 ) »
msfox hat geschrieben:
29.10.2024 11:55
Ich kenne das noch aus meinen Programmieranfängen in JAVA, dass man Dinge prüft und nicht einfach auf eine Exception laufen lässt.
Könnte man in ABAP ja auch machen mittels line_exists( ), aber in Fällen wie bei dir mache ich so was nie, da man dann durch das nachfolgende Read im TRUE-Fall ja 2x auf die Zeile zugreifen muss ( und ich nirgends in der Doku was gelesen habe, dass SAP in diesem Fall die auf Existenz geprüfte zeile irgendwo gepuffert vorhält für einen Folgezugriff ).
Ansonsten sind die beiden Versionen mittels lt_data[ .. ] der READ TABLE (egal ob mit INTO DATA() oder ASSIGNING FIELD-SYMBOL( ) ) eigentlich fast gleichwertig. Die Sonderfälle ( wie z.B. dass READ TABLE den SY-TABIX bei Erfolg und sinnvoll definierten Tabellen setzt ) sind rar gesät und wenn du es brauchst wirst du die dann bevorzugte Methode wählen.
Das ist so eine der Stellen, wo ich sagen würde, dass der Entwickler sich an den Stil des herumliegenden Codes hält oder einfach seinen eigenen Stil suchen sollte.
Ich persönlich verwende beides zu etwa 50% und habe keine Vorliebe.
live long and prosper
Stefan Schmöcker

email: stefan@schmoecker.de

Re: Exception statt sy-subrc

Beitrag von black_adept (Top Expert / 4087 / 126 / 940 ) »
msfox hat geschrieben:
29.10.2024 12:58
...Es soll alles funktionsorientiert programmiert werden. Für mein Verständnis steht dafür der Zielwert immer links vom = und der Quellwert rechts. Das wäre bei einem ASSIGN nicht so. Darum wird auch überall von MOVE-CORRESPONDING auf xyz = CORRESPONDING umgestellt.
Arbeitsbeschaffungsmaßnahmen? Dann ersetzt ihr bestimmt auch ADD mit +=.
Und ein Hinweis, da es häufiger vergessen wird: Wenn ihr auf CORRESPONDING #( ) umstellt, dann aber immer mit BASE, da es sonst im Allgemeinen nicht funktionsgleich ist.
live long and prosper
Stefan Schmöcker

email: stefan@schmoecker.de

Re: Exception statt sy-subrc

Beitrag von DeathAndPain (Top Expert / 1939 / 257 / 412 ) »
msfox hat geschrieben:
29.10.2024 12:58
Wenn ich ein ASSIGN mache und es die Zeile nicht gibt, dann wird wohl keine cx_sy_itab_line_not_found geworfen?
ASSIGN dumpt niemals (und wirft dementsprechend niemals Exceptions), sondern setzt den SY-SUBRC. Das macht den Befehl so angenehm in der Handhabung. Dere Anteil der Fälle, in denen sich der sperrige READ TABLE-Befehl durch ASSIGN ersetzen lässt, liegt nahe bei 100%. READ TABLE braucht man eigentlich nur noch dann, wenn man effizient in einer binärsortierten Standardtabelle suchen möchte (was man in fast allen Fällen gar nicht erst tun, sondern stattdessen eine sortierte oder gehashte Tabelle verwenden sollte) oder wenn man den SY-TABIX der Fundstelle braucht (was fast nie vorkommt).
msfox hat geschrieben:Dein Beispiel würde vermutlich andere Diskussionen hervorrufen. Es soll alles funktionsorientiert programmiert werden. Für mein Verständnis steht dafür der Zielwert immer links vom = und der Quellwert rechts. Das wäre bei einem ASSIGN nicht so. Darum wird auch überall von MOVE-CORRESPONDING auf xyz = CORRESPONDING umgestellt.
Nur zum Verständnis: Auf dem Altar dieser Ideologie soll der ganze ASSIGN-Befehl geopfert werden? Und dann macht ihr Klimmzüge, wie ihr mit ABAP irgendwie anders Fälle lösen könnt, bei denen ASSIGN der passende Befehl wäre?

Sorry, aber das empfinde ich als geisteskrank, aus einer Programmiersprache willkürlich Befehle nicht zu verwenden, weil sie einem selbstdefinierten Dogma widersprechen. Wenn sie veraltet sind oder man andere handfeste Gründe und vor allem gute Alternativen hat, ok. Aber READ TABLE hat genauso die Quelle links und das Ziel rechts. Stattdessen einfach zuzuweisen und dadurch ständig Exceptions behandeln zu müssen, die das kosmetisch scheußliche TRY-CATCH-ENDTRY-Konstrukt erfordern und zudem mies in der Performance sind, kann doch nicht die Alternative sein. Vor allem nehmt ihr euch damit ja auch die Möglichkeit, mit Feldsymbolen zu arbeiten, denn alle Syntaxen, die mir einfallen (sei es ASSIGN, sei es READ TABLE, sei es inline mit ASSIGNING FIELD-SYMBOL) haben das Zielfeld rechts zu stehen. Ihr streicht euch also das halbe ABAP weg und überlegt euch Krücken, wie ihr das trotzdem irgendwie programmiert bekommt.

Ernsthaft!?

Re: Exception statt sy-subrc

Beitrag von rob_abc (Specialist / 106 / 27 / 44 ) »
DeathAndPain hat geschrieben:
29.10.2024 19:00
Sorry, aber das empfinde ich als geisteskrank
Weniger geht nicht? o.0

Die Kombination aus VALUE und OPTIONAL dumpt auch nicht.

Code: Alles auswählen.

SELECT * from t002 into table @DATA(languages).
DATA(suaheli) = VALUE #( languages[ laiso = 'sw' ] OPTIONAL ).
IF suaheli IS INITIAL.
  cl_demo_output=>display( 'Raise Dump' ).
ENDIF.
Wobei man da beachten muss, dass subrc nicht ungleich 0 gesetzt wird, wenn der table expression nichts findet und leer nicht heissen muss, dass nichts gefunden wurde. Daher verwende ich auch eher ASSIGN, falls nichts finden nicht ok ist und ich darauf reagieren muss.

Re: Exception statt sy-subrc

Beitrag von gtoXX (Specialist / 213 / 44 / 36 ) »
DeathAndPain hat geschrieben:
29.10.2024 12:32
Eine Exception - gerade eine klassenbasierte - kostet eine ganze Stange Performance. Das ist egal, wenn es wirklich ein Ausnahmefall ist, der nur alle Jubeljahre mal auftritt. Allerdings willst Du in Deinem Beispiel ja tatsächlich (so oder so) eine Exception werfen. Ich meine, dass es Standpunkt der SAP ist, dass man dann modernerweise klassenbasiert mit TRY...CATCH vorgehen soll.
Diese Aussage ist nicht korrekt. Grundsätzlich wird ein Ausnahmeobjekt erst erzeugt, wenn beim CATCH ein INTO erfolgt. Und gravierend ist diese Erzeugung auch nicht.

Folgende Benutzer bedankten sich beim Autor gtoXX für den Beitrag:
ewx

"Code lügt nicht ^^"

Re: Exception statt sy-subrc

Beitrag von gtoXX (Specialist / 213 / 44 / 36 ) »
msfox hat geschrieben:
29.10.2024 11:55
Es gibt bei uns gerade eine Diskussion unter den Entwickler, was richtig ist.

Geht hier nur ums Prinzip.
Die Frage stellt sich nicht aus Prinzip, sondern aus dem Kontext des Codings.

Eine Exception lässt sich innerhalb einer Aufrufhierarchie leicht behandeln. Wenn ich also nicht genau weiß, wer einen Fehler in einer Methode behandelt, ist eine Exception zu verwenden.

Wobei in dem Beispiel hier ein TRY CATCH mit RAISE nicht unbedingt sinnvoll ist, da die Exception cx_sy_itab_line_not_found schon eine klare Aussage über die Art des Fehler gibt. Macht also die weitere Programmausführung aufgrund des fehlenden Eintrags keinen Sinn, delegiert man einfach diese Exception in dem man sie nicht abfängt.

SAP empfiehlt zum Beispiel auch REFERENCE INTO statt FIELD-SYMBOL. Da der Syntax mit dem REF->* dem von OO ähnlicher ist.
"Code lügt nicht ^^"

Re: Exception statt sy-subrc

Beitrag von msfox (Specialist / 364 / 56 / 74 ) »
DeathAndPain hat geschrieben:
29.10.2024 19:00
Sorry, aber das empfinde ich als geisteskrank, aus einer Programmiersprache
Ich muss MICH da mal rausnehmen. Bin da nur extern...

Re: Exception statt sy-subrc

Beitrag von msfox (Specialist / 364 / 56 / 74 ) »
DeathAndPain hat geschrieben:
29.10.2024 19:00
TRY-CATCH-ENDTRY-Konstrukt erfordern und zudem mies in der Performance
Kannst du mir das irgendwie belegen?
Wie geschrieben bin ich nur extern beratend. Ich kann aber nun nicht zum Entwickler gehen und sagen, mach das so nicht. Und wenn ich ihm sage, dass das unperformant ist, will er das auch bewiesen haben, da er auch nur nach Vorgaben arbeitet und eben diese Vorgaben vorher angepasst werden müssen....

Re: Exception statt sy-subrc

Beitrag von gtoXX (Specialist / 213 / 44 / 36 ) »
msfox hat geschrieben:
30.10.2024 10:03
DeathAndPain hat geschrieben:
29.10.2024 19:00
TRY-CATCH-ENDTRY-Konstrukt erfordern und zudem mies in der Performance
Kannst du mir das irgendwie belegen?
Wie geschrieben bin ich nur extern beratend. Ich kann aber nun nicht zum Entwickler gehen und sagen, mach das so nicht. Und wenn ich ihm sage, dass das unperformant ist, will er das auch bewiesen haben, da er auch nur nach Vorgaben arbeitet und eben diese Vorgaben vorher angepasst werden müssen....
Kann er nicht. TRY-CATCH-ENDTRY ohne ein INTO, wo ein Ausnahmeobjekt erzeugt wird, hat 0-Performance-Impact. Ausnahmeobjekte werden erst dann erzeugt, wenn sie tatsächlich benötigt werden. Desweiteren habe ich bei Ausnahmeobjekten natürlich mehrere Vorteile. Ich kann Kontext mitgeben, untergeordnete Fehlerobjekte, habe gegebenenfalls einheitliche Fehlermeldungen etc.
"Code lügt nicht ^^"

Re: Exception statt sy-subrc

Beitrag von rob_abc (Specialist / 106 / 27 / 44 ) »
gtoXX hat geschrieben:
30.10.2024 10:42
Kann er nicht. TRY-CATCH-ENDTRY ohne ein INTO, wo ein Ausnahmeobjekt erzeugt wird, hat 0-Performance-Impact.
Wenn ich das Demo-Programm in der SAT ausführe, dann sehe ich einen Performanceunterschied zwischen CATCH cx_sy_itab_line_not_found und dem Rest (3 Sekunden zu 1 Sekunde). Ob der relevant ist, muss man halt am spezifischen Fall beurteilen.

Code: Alles auswählen.

REPORT.

CLASS lcl_report DEFINITION CREATE PRIVATE.

  PUBLIC SECTION.
    CLASS-METHODS main.

  PRIVATE SECTION.
    CLASS-DATA tadir1 TYPE sorted TABLE OF tadir with non-unique key obj_name.
    CLASS-DATA tadir2 TYPE sorted TABLE OF tadir with non-unique key obj_name.

    CLASS-METHODS do_assign.
    CLASS-METHODS do_value.
    CLASS-METHODS do_exception.

ENDCLASS.


CLASS lcl_report IMPLEMENTATION.
  METHOD main.
    SELECT * FROM tadir INTO TABLE tadir1 UP TO 1000000 ROWS.
    tadir2 = tadir1.
    do_exception( ).
    do_assign( ).
    do_value( ).
  ENDMETHOD.

  METHOD do_assign.
    LOOP AT tadir1 ASSIGNING FIELD-SYMBOL(<line>).
      ASSIGN tadir2[ obj_name = |{ <line>-obj_name }1| ] TO FIELD-SYMBOL(<fs1>).
      IF sy-subrc <> 0.
        "ASSIGN tadir2[ obj_name = <line>-obj_name ] TO FIELD-SYMBOL(<fs2>).
      ENDIF.
    ENDLOOP.
  ENDMETHOD.

  METHOD do_value.
    LOOP AT tadir1 ASSIGNING FIELD-SYMBOL(<line>).
      DATA(line) = VALUE #( tadir2[ obj_name = |{ <line>-obj_name }1| ] OPTIONAL ).
      IF line IS INITIAL.
        "DATA(line2) = VALUE #( tadir2[ obj_name = <line>-obj_name ] OPTIONAL ).
      ENDIF.
    ENDLOOP.
  ENDMETHOD.

  METHOD do_exception.
    LOOP AT tadir1 ASSIGNING FIELD-SYMBOL(<line>).
      TRY.
          DATA(line) = VALUE #( tadir2[ obj_name = |{ <line>-obj_name }1| ] ).
        CATCH cx_sy_itab_line_not_found.
          "DATA(line2) = VALUE #( tadir2[ obj_name = <line>-obj_name ] ).
      ENDTRY.

    ENDLOOP.
  ENDMETHOD.
ENDCLASS.

START-OF-SELECTION.
  lcl_report=>main( ).

Re: Exception statt sy-subrc

Beitrag von DeathAndPain (Top Expert / 1939 / 257 / 412 ) »
rob_abc hat geschrieben:Weniger geht nicht? o.0
Ich weiß, was Du meinst, aber in diesem Fall geht wirklich nicht weniger. Das ist keine Frage persönlichen Geschmacks mehr. Man kann sich doch nicht entscheiden, eine Programmiersprache (ABAP) zu verwenden und dann willkürlich die Verwendung ganz zentraler Befehle daraus zu verbieten. Wenn jemand irgendwelche Exotenbefehle wie ASSERT oder das REDUCE-Konstrukt nicht einsetzen möchte, ist das in Ordnung. Aber ASSIGN!? Das ist ja nun wirklich ein ganz zentraler Kernbefehl von ABAP.
rob_abc hat geschrieben:Die Kombination aus VALUE und OPTIONAL dumpt auch nicht.
Ja, aber wie Du schon richtig anmerkst, kann man einem initialen Ergebnis nicht anmerken, ob der gefundene Wert initial war oder gar kein Wert gefunden worden ist. In vielen Fällen ist das trotzdem gut genug (das oder DEFAULT mit einem Wert, der bei einem Fund realistischerweise nicht vorkommen kann), aber hier wurde ja explizit nach einer akademischen Antwort gefragt, und da halte ich den OPTIONAL-Ansatz für nicht gut genug.
msfox hat geschrieben:Ich muss MICH da mal rausnehmen. Bin da nur extern...
Ja, darauf hast Du hingewiesen. Das war auch kein Vorwurf an Deine Adresse, sondern an die desjenigen, der sich so eine Vorschrift ausgedacht und sie ernsthaft durchgesetzt hat. Da kann man sich echt nur fremdschämen.
gtoXX hat geschrieben:Kann er nicht. TRY-CATCH-ENDTRY ohne ein INTO, wo ein Ausnahmeobjekt erzeugt wird, hat 0-Performance-Impact.
Nett behauptet, aber hast Du es mal durchgemessen? Also eine Ausnahmeerzeugung per CATCH gegen die simple Abfrage des SY-SUBRC? Ich ja, und ich habe es hier in diesem Forum diskutiert. Logischerweise finde ich den Thread nicht mehr; das ist Jahre her, aber nach meiner Erinnerung hat der CATCH-Ansatz siebenmal so lange gedauert wie der mit dem SY-SUBRC. Natürlich nur in Fällen, in denen die Ausnahme tatsächlich feuert. Deswegen ja "Ausnahme", denn in seltenen Ausnahmefällen gibt das keinen nennenswerten Performance-Impact. Wenn man freilich z.B. in einer Schleife einen gewöhnlichen IF damit ersetzt, wo häufig der betreffende Fall eintritt, dann kann das durchaus einen Unterschied machen.

Das Ganze kannst Du leicht mit einem passenden Testprogrämmchen nachmessen. Wie gesagt, ich habe es gemacht, und ich werde das Programm jetzt nicht nochmal bauen, nur um Dir was zu beweisen. Aber rob_abc ist ja so freundlich gewesen. Rasch mal die dreifache Laufzeit des Gesamtkonstrukts ist ja schon eine Ansage.

Re: Exception statt sy-subrc

Beitrag von msfox (Specialist / 364 / 56 / 74 ) »
Danke für den Report zur Messung. Habe ich mal so übernommen und noch ergänzt um READ TABLE ... REFERENCE INTO und READ TABLE .... INTO. Erstaunlich, dass letzteres das schnellste war. Ich hab die Methode dafür auch extra an erste Stelle gepackt, damit nicht die SAP irgendwas cached...

Vergleichbare Themen

2
Antw.
2834
Views
sy-subrc oder syst-subrc?
von genua » 31.10.2007 11:55 • Verfasst in ABAP® für Anfänger
8
Antw.
6119
Views
MB_CREATE_GOODS_MOVEMENT mit SUBRC 5
von Adrian » 20.04.2015 14:34 • Verfasst in ABAP® für Anfänger
2
Antw.
3223
Views
Übersicht zu sy-subrc
von KleinerEisbaer » 22.07.2008 16:48 • Verfasst in ABAP® für Anfänger
1
Antw.
4998
Views
Unterprogramm + sy-subrc setzen
von fabis » 26.01.2012 18:10 • Verfasst in ABAP® für Anfänger
7
Antw.
2638
Views
AlV Grid Sy-subrc = 4 MIST!!!
von tho_died » 12.06.2007 13:20 • Verfasst in ABAP® Core

Newsletter Anmeldung

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

Unbeantwortete Forenbeiträge

Daten an Tabelle binden
Gestern von Bright4.5 1 / 516
aRFC im OO-Kontext
vor 4 Wochen von ralf.wenzel 1 / 2149
Hilfe bei SWEC/SWE2
letzen Monat von retsch 1 / 8744