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.
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.
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.
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 ).
Arbeitsbeschaffungsmaßnahmen? Dann ersetzt ihr bestimmt auch ADD mit +=.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.
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).
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?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.
Weniger geht nicht? o.0
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.
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.DeathAndPain hat geschrieben: ↑29.10.2024 12:32Eine 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.
Die Frage stellt sich nicht aus Prinzip, sondern aus dem Kontext des Codings.
Ich muss MICH da mal rausnehmen. Bin da nur extern...DeathAndPain hat geschrieben: ↑29.10.2024 19:00Sorry, aber das empfinde ich als geisteskrank, aus einer Programmiersprache
Kannst du mir das irgendwie belegen?DeathAndPain hat geschrieben: ↑29.10.2024 19:00TRY-CATCH-ENDTRY-Konstrukt erfordern und zudem mies in der Performance
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.msfox hat geschrieben: ↑Gestern 10:03Kannst du mir das irgendwie belegen?DeathAndPain hat geschrieben: ↑29.10.2024 19:00TRY-CATCH-ENDTRY-Konstrukt erfordern und zudem mies in der Performance
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....
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( ).
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:Weniger geht nicht? o.0
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.rob_abc hat geschrieben:Die Kombination aus VALUE und OPTIONAL dumpt auch nicht.
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.msfox hat geschrieben:Ich muss MICH da mal rausnehmen. Bin da nur extern...
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.gtoXX hat geschrieben:Kann er nicht. TRY-CATCH-ENDTRY ohne ein INTO, wo ein Ausnahmeobjekt erzeugt wird, hat 0-Performance-Impact.