Delete specific row in ALV? - abap

I want to delete a specific row in a table. I identified the row before using get_selected_rows. Now I have the row identified in gt_rows.
Now I want to delete that row. I just can't get it done. Here's my current code:
go_selec = go_alv->get_selections( ). "gt_rows
CALL METHOD go_selec->get_selected_rows
RECEIVING
value = gt_rows.
*Here the row should get deleted.
The name of the database Table is "zrtable" and the name of the internal table is it_table. The name of the structure is ls_table. I'm a beginner so a bit of code would be awesome. :)

gt_rows table holds index data of the rows which selected.
Now you have to loop at your index table to read these lines.
LOOP AT gt_rows ASSIGNING FIELD-SYMBOL(<index>).
READ TABLE it_table ASSIGNING FIELD-SYMBOL(<table_line>) INDEX <index>.
IF <table_line> IS ASSIGNED.
CLEAR <table_line>.
ENDIF.
ENDLOOP.
Also instead of READ TABLE, you can use,
DATA(line) = it_table[ index ].
Think field-symbols as pointers, you directly access to data using them, so they point the reference not value.

Related

Is there any way to use a variable with data change triggers (old./new.) for a trigger function?

I am writing a function in PostgreSQL for a trigger where I want to log a change (update) on one table (core_table) and insert it into another table (audit_table) but only have it insert the columns that were actually changed. The way I am going about it is this:
IF (old.color <> new.color) then
insert into audit_table select 'core_table', Data, old.color, new.color;
end if;
I have it working hardcoded (where I have ~40 IF statements to handle each column) but I want to turn it into a loop. I have a dynamic SQL inside this function that returns the name of the next column for each iteration into a variable named "Data" (on loop 1 Data = "color", loop 2 Data = "model", etc.)
The problem now is that when I replace old.color with old.Data it tells me that there is no column named "Data" (SQL Error [42703]: record "old" has no field "column_name") it is not reading the value stored in Data (which is "color") but the name of the variable itself ("Data").
So my question is this, is there any way to use a variable with data change triggers (old./new.) for a trigger function?

get ERROR "Internal tables cannot be used as work areas" inside of method

I am new with ABAP. I asked a similar, but different, question to this one yesterday.
I duplicate a table (= table) to a local table (= localTable) and remove all duplicates in it, this works fine (first 3 code lines)
Now I want to loop over this local table and send all matching data into an structure with INTO CORRESPONDING FIELDS OF - unfortunately I always get the following error:
Internal tables cannot be used as work areas.
INFO: I'm working inside of a method!
Here is my code where I'm working with:
DATA localTable TYPE STANDARD TABLE OF table.
SELECT columnName FROM table INTO TABLE localTable.
DELETE ADJACENT DUPLICATES FROM localTable COMPARING columnName.
LOOP AT localTable ASSIGNING FIELD-SYMBOL(<fs_table>).
SELECT * FROM anotherTable as p
WHERE p~CN1 = #localVariable
AND p~CN2 = #<fs_table>-columnName
INTO CORRESPONDING FIELDS OF #exportStructure "<-- Here I always get my error
ENDSELECT.
ENDLOOP.
First: I've read that I have to sort my internal table before using command DELETE ADJACENT DUPLICATES FROM localTable COMPARING columnName. so I've added following code line in between:
SORT localTable BY columnName ASCENDING.
Second: Instead of using INTO CORRESPONDING FIELDS OF TABLE I've used APPENDING CORRESPONDING FIELDS OF TABLE because INTO overwrites every line with itself, so in total I have only one line in my exported structure.
APPENDING adds a new line every time my statements are true.

how to SAFE_CONVERT_BYTES_TO_STRING and REPLACE?

i got a table with three columns whose type is BYTES
i succeed to make a SELECT SAFE_CONVERT_BYTES_TO_STRING
but now, i wish i could REPLACE my BYTES values by their corresponding STRING in my original table
Replacing the value would imply changing the column type, which is not supported.
My recommendation would be to save your query results to a different destination table then drop the current table and copy the destination table to rename it as the original one.

Updating a table column using LIKE in WHERE

I have a table(ENTITY) that needs to be updated based on an ID(FUNNCODE) but the ID(FUNNCODE) is linked between two other tables(from JOINT then to POSITION)
and is independent of where the data is at(table NEORSD). The only parameter I can bind is the position name between the NEORSD table and POSITION table. When I place my LIKE statement into the where clause I get an error in return. If anyone can point me in the right direction it would be greatly appreciated!
Tables:
NEORSD: Contains the range information and 'position name(= Tag_No)'
ENTITY: Needs to update and accept the range information (Holds FUNCCODE)
JOINT: Holds FUNCCODE(named POSFUNCCODE) and corresponding POSCODE
POSITION: Contains POSCODE and 'position name(=POSID)'
UPDATE ENTITY
SET
RANGE0 = (
SELECT RANGE0
FROM NEORSD_1199
WHERE Tag_No like ('%PIT%'))
WHERE
FUNCCODE = (
SELECT POSFUNCCODE
FROM JOINT
WHERE POSCODE = (
SELECT POSCODE
FROM POSITION
WHERE POSID like ('%PIT%'))
If NEORSD_1199 has more than one row with a tag_no like '%PIT%', which NEORSD_1199.RANGE0 value should it use to update ENTITY.RANGE0?
This is the db engine's problem with your SQL.
To better understand, read the SQL backwards:
First you're getting a list of every Position Code from the POSITION table where the Position ID is like '%PIT%'. That might be one code, and it might be one hundred codes.
Then you're getting every Position Function Code from the JOINT table where the Position Code is in the list of Position Codes you just gathered. Again, could be one, could be a hundred.
Then you're getting a list of all values of RANGE0 from the NEORSD1199 table where Tag_No is like '%PIT%'. Again, this could be one value, or a list of one hundred.
Then, you're getting every row from the ENTITY table where the Function Code is in the list of Position Function Codes you gathered from the JOINT table (step 2 above), and you're updating RANGE0 in each of these rows to the value you captured in step 3.
The problem is that the 'value' returned in step 3 could be a list of values. If
NEORSD1199 has four rows where tag number is like '%PIT%'
(e.g. PIT01,PIT02,PIT03,APIT00), and each of those rows has a different
RANGE0 (e.g. 1,2,3,99), then which of those four values should the DB engine use to update RANGE0 in the rows in the ENTITY table?
Thank you to #SQLCliff for the questions that help to find the solution. I created an ID column inside my NEORSD table, created a temporary table holding the link between FUNCCODE and the ranges in NEORSD. Then I updated ENTITY using a join on. I can insert the where clause at the end of the temporary table for filtering if needed. Since it is a mass update I no longer require a where clause. My brain just likes making things more complicated than they need to be XD
with t as(
select f.funccode as funccode ,n.range0, n.range100
from func as f
join NEORSD_1199_With_Ranges_Updated as n on n.id = f.poscode or n.id =f.devcode
/* WHERE nessecrary ;P*/)
update entity
set
range0 = t.range0,
range100 = t.range100
from entity as e
join t on e.funccode = t.funccode

Get values based on newly inserted value using SQL

I want to make filtration on a column after selecting a specific value of another column in the same table, I tried to use #... special character followed by the column's name to get the address of this value.
My SQL statement is like the following :
SELECT ATTRIBUTE FROM TABLE WHERE FIELD = '#FIELDNAME';
If I used a specific value instead of #FIELDNAME, it will work properly but it will be static but I need it to be dynamic based on the selected value.
Create another table which will have the list of values that are in the FIELDNAME and give each record a unique id ,then retrieve the value depending on what you have selected by the name of the new table's field preceded by '#...'
I don't know if that what are you looking for, please let me know.
If no triggers are allowed, do you have any date/time column in the table? Is it possible to have that extra column anyway to see the time of a newly inserted row?
You may have to check the lastest row entered, save its field value into a variable. Then do the select based on the variable value.
Based on the vague last row id you could try the following (it's not pretty). But again, if you have date/time that's more accurate.
select attribute from table
where field = (select field from table
where rowid =(select max(rowid) from table))
;
upate
Do you have the priviledge to set up your insert command as below:
insert into table (id, col1, col2,...) values (1,'something', 'something',...)
returning id into variable; -- you may either save field or id depending on your table
Then you may use this variable to select the records you want.