Best way to modify a DB Table from a work area in ABAP - abap

I want to find out the best solution for modifying a DB table from work area in a loop.
There are several ways to achieve that, first;
LOOP AT itab INTO wa.
wa-flag = 'X'.
MODIFY zblabla FROM wa.
ENDLOOP.
and field symbol;
LOOP AT ITAB ASSIGNING <WA>.
<WA>-flag = 'X'.
ENDLOOP.
Or, should I modify the DBtable from whole internal table ?
modify zblabla from it.
I'm not sure which one is a better approach for less than 50 entries. (I also want to know which one is better with much more entries. )
Thanks.

Your first example (the one with LOOP AT ITAB ASSIGNING <WA>) does not actually change the database. It only changes the data in memory. However, you can afterwards do UPDATE zblabla FROM TABLE itab. which sends the whole table back to the database at once.
When every single line of the table changed, this is far faster than changing every line individually. But when only a few lines of the table are actually different, this is quite wasteful and it will likely be faster to update only the lines which actually changed using MODIFY.
Another option which can sometimes be used to update database content without even loading it into the application server is the UPDATE database_table SET field = value WHERE condition command.
UPDATE zblabla SET flag = 'X'.
Would set the flag to 'X' for every single row in the table right on the database without even having to SELECT anything.
In your example it would be by far the fastest method, but in the real world you rarely have problems which are so trivial.
UPDATE ... SET ... WHERE ... should also be preferred over MODIFY for single entries when the table you have is very wide and you didn't change most of it because it allows you to specify the fields you want to change. You also must use it when you don't got your data through a SELECT * but instead only queried individual fields.

First modify the data in the loop using a field symbol
LOOP AT ITAB ASSIGNING <WA>.
<WA>-flag = 'X'.
ENDLOOP.
i would suggest you to use UPDATE over MODIFY.
UPDATE DBTAB from TABLE ITAB.
If you want to use Modify statement to update the DB.
MODIFY DBTAB from ITAB.

modify a internal table using transporting and where clauses to specify which fields will be altered using the whole key of the table and then using the internal table change the transparent table (database table).
wa_X-field1 = "something". "where wa_X is of the same type of the table e.g. has the same "fields.
wa_X-field2 = "other something".
MODIFY it_tableX FROM wa_X TRANSPORTING field1 field2 WHERE key1 = wa_X-key1 "(first key)
key2 = wa_X-key2. "(last key)
MODIFY tableX FROM TABLE it_tableX.
This is usually better because it increases performance and assures that you only alter the lines of the table that you mean to change.
Hope this helps.

Related

How to reset the table values in AX 2012?

Can I use like this to reset the table variable in AX?
I have tried with the below piece of code:
Table_Name.RecId=0;
You can use the .clear() method that is available on all tables to clear/reset all table fields, including the RecId field.
Table_Name.clear();
Have you considered deleting the record instead?
Table_Name.delete();
The field RecId identifies the record and cannot meaningful be reset.
Clear is to erase field values of te object in order to rehuse the object in a loop. Delete has a direct impact into SQL Database.
Full reset for all data fields and behaviour features:
TableName = null;
see feature example. TableName.clear(); clears only data fields.

How to deselect values in multivalue lookup field using a query

I want to delete all the data of a single field. This field is a ''multipled value lookup field'';
I tried this query in the SQL design tab:
UPDATE _myDatabase SET [_myDatabase].mycolumn= Null;
but it's not working (although it works for a any non-lookup fields). Any idea how to solve this?
Because you are using a multi value field, you must treat the field as a separate table, which it actually is under the hood.
So you use a DELETE statement:
DELETE _myDatabase.mycolumn.Value FROM _myDatabase

SQL, when adding a field to database put in two fields and modify

I have this database setup:
http://sqlfiddle.com/#!12/b2989
I want to add a record called "solrID" under item where I already have "ID".
Is it possible to have SQL setup so whenever an entry gets put into ID I also add the same value into SOLRID, except I start it with the text "app".
Therefore, when I add a record to my "item" table, ID autoincrements to have a value of say "2" then I want SOLRID to automatically have the value "app2".
Is this possible?
Two choices that comes to mind is create a view that creates solrID on the fly, or if you really want to have a column that stores what is basically redundant data you can use a trigger to populate solrID.
For me, knowing only what I know from your message I would consider using a view unless you have a really reason to store solrID in the actual table.

How to use a dynamic variable in SQL statement

I am creating an upate trigger. I have a situation where I need to test a condition on a table column, without actually knowing what the exact column name is. The trigger is generic and can applied to any table, with varying columns.
Pseudo-code:
// define a cursor that loops through all columns in "MyTable"
Define cursor C1 for (select COLS from SYSCAT.TABLES where TABS="MyTable")
FOR
// take the next column from the cursor
#temp_var = C1.COLS
// DELETED and INSERTED are tables that also contain the same columns as "MyTable" table.
if(DELETED.#temp_var <> INSERTED.#temp_var)
THEN
...
The above statement if(DELETED.#temp_var <> ... does of course not work, but maybe you can see what I am trying to do? So I would want it to be during runtime e.g. if(DELETED.MyColumn <>... where "MyColumn"is a column in"MyTable"and also inINSERTEDandDELETED columns. Note that because this method should be generic, I do not know beforehand what columns the table has (depends on the specific table in use).
Any ideas on how to build the if-statement dynamically like that?
In DB2 SQL you cannot refer to columns dynamically. So, you won't be able to do that using only SQL. You could possibly call an external procedure written in another language from within the trigger. Or, you could rethink your overall design for what you are trying to do. I don't see any other options.

How to know if selection-screen is filled or not?

I have selection screen with SELECT-OPTION let say the name is selection_kunnr and I want to know if user filled that selection area or not
Note: this selection_kunnr is not a mandatory field. How can I deal with it?
I have tried so far
if selection_kunnr is not initial.
"do some action here
endif.
but I think it doesn't work at all.
Any suggestions?
SELECT-OPTIONS create an internal table (same as the RANGE statement) for a field. (It creates 4 fields: SIGN, OPTION, LOW and HIGH). You can check whether the table has any contents by using:
IF SELECTION_KUNNR[] IS INITIAL.
The [] operator specifies the contents (rows) of an internal table.
I am not sure anymore, because I am not in front of an SAP system right now, but if only the initial FROM/TO fields are filled, I am not sure whether this creates an entry in the table.
HINT: In the ABAP editor, you can place the cursor on any statement, and press F1 to get help on that statement.
Given that this creates an internal table you can also use the DESCRIBE statement. Which works just as well on ranges and internal tables in your program.
DESCRIBE TABLE LINES w_count.