Error in select no header - abap

I want make select from EPREI to ET_DATA ET_DATA have prices prices is structure what i want fill it from EPREIH...
*"----------------------------------------------------------------------
*"*"Lokálne rozhranie:
*" IMPORTING
*" REFERENCE(I_PREIS) TYPE ZRT_IWP_CPREISTYP OPTIONAL
*" EXPORTING
*" REFERENCE(ET_DATA) TYPE ZTT_IWPIFC_PRICE
*" EXCEPTIONS
*" NO_DATA_SELECTED
*"----------------------------------------------------------------------
field-symbols: <lfs_ET_DATA> like line of ET_DATA.
refresh ET_DATA.
SELECT *
FROM EPREI
into CORRESPONDING FIELDS OF TABLE ET_DATA.
loop at ET_DATA assigning <lfs_ET_DATA>.
select *
from EPREIH
into CORRESPONDING FIELDS OF TABLE ET_DATA-prices
where PREIS = <lfs_ET_DATA>-PREIS
and PREISTYP <= <lfs_ET_DATA>-PREISTYP.
endloop.
it shows error:
"ET_DATA" is table without hedaer line and therefore have not component call prices.
How can i make this select correctly? Sorry for my english but i am so tired...

As the previous answer said, ET_DATA is a reference to a table type and does not have a work area.
So if you really want to add a list of EPREIH into ET_DATA-PRICE you have to point to the work area which is assigned to your field symbol.
Something like this:
field-symbols: <lfs_ET_DATA> like line of ET_DATA.
refresh ET_DATA.
SELECT *
FROM EPREI
into CORRESPONDING FIELDS OF TABLE ET_DATA.
loop at ET_DATA assigning <lfs_ET_DATA>.
select *
from EPREIH
into CORRESPONDING FIELDS OF TABLE <lfs_ET_DATA>-prices
where PREIS = <lfs_ET_DATA>-PREIS
and PREISTYP <= <lfs_ET_DATA>-PREISTYP.
endloop.
extra tip: try using pretty printer with "keywords uppercase" and avoid "select *" if you are not using all fields from those tables.

I'm not entirely sure what you are trying, but it looks like you want to update the field "prices" of table ET_DATA.
If you have 1 record in EPREIH for each record in EPREI, your select should look like this :
loop at ET_DATA assigning <lfs_ET_DATA>.
select single prices
from EPREIH
into <lfs_ET_DATA>-prices
where
PREIS = <lfs_ET_DATA>-PREIS
and PREISTYP <= <lfs_ET_DATA>-PREISTYP.
endloop.
You are using a field (ET_DATA-prices) as a table (INTO CORRESPONDING FIELDS OF). That will not work.

Firstly, the reason you are getting the syntax error is that you would need to update ET_DATA with a work area (structure declared as a line of the same type as the table).
What your code will end up doing though is replacing records in ET_DATA on the second select, on each iteration of your loop, so that will accomplish nothing.
You could most like select everything in one SELECT by using a JOIN:
SELECT E1~FIELD1 E2~FIELD2 (etc.)
FROM EPREI as E1
JOIN EPREIH as E2
ON E2~PREIS = E1~PREIS AND
E2~PREISTYP = E2-PREISTYP
into CORRESPONDING FIELDS OF TABLE ET_DATA.
You will just need to change the field specifications in the SELECT clause above to match the fields in your table (and you could leave out the CORRESPONDING).
And you should probably limit the selection on EPREI with a WHERE clause.

Related

use SELECT on internal table (ABAP)

I am still very inexperienced with SAP ABAP.
I have an internal table that I want to filter further and further based on whether data is present.
I have tried the following, but unfortunately I cannot apply a SELECT to an internal table.
How can I solve this problem?
Hope I have explained my problem clearly enough!
"Here I'm getting the hole database into my internal table
SELECT * FROM TABLE
INTO CORRESPONDING FIELDS OF TABLE #itab.
"This should be my first filter if iv_name is not initial
IF iv_name IS NOT INITIAL.
SELECT * FROM itab
WHERE NAME = #iv_name
INTO CORRESPONDING FIELDS OF TABLE #itab.
ENDIF.
"This should be my second filter if iv_age is not initial
IF iv_age IS NOT INITIAL.
SELECT * FROM itab
WHERE AGE = #iv_age
INTO CORRESPONDING FIELDS OF TABLE #itab.
ENDIF.
There are several ways in ABAP to achieve your goal.
You can use the DELETE keyword to filter the data in an internal table:
IF iv_name IS NOT INITIAL
DELETE itab WHERE name NE iv_name.
ENDIF.
Another possibility is to use the FILTER keyword, but the prerequisite is, that the internal table is TYPE SORTED or HASHED:
itab = FILTER #( itab WHERE name = iv_name ).

How to select and commit data to DB by chunks?

I have written a code to get all records into internal table using select query, perform concatenation on it and update the DB from this internal table.
To improve performance how can I select specific number of records like 1000 records, process them and after updating the DB select next 1000 records and so on.
Here is my code
DATA: lv_index_table TYPE /ngv/b0tabnm,
lref_tname TYPE REF TO data.
FIELD-SYMBOLS: <lt_indx_table> TYPE ANY TABLE,
<lwa_indx_table> TYPE any.
CALL METHOD /ngv/cl_bmtr_framework=>generated_table_get
EXPORTING
i_dtarea = /ngv/if_bcon=>mc_data_area-index
IMPORTING
e_table = lv_index_table "here i get DB table name .
EXCEPTIONS
table_not_found = 1
OTHERS = 2.
CHECK lv_index_table IS NOT INITIAL.
CREATE DATA lref_tname TYPE TABLE OF (lv_index_table).
ASSIGN lref_tname->* TO <lt_indx_table>.
CHECK <lt_indx_table> IS ASSIGNED.
SELECT * FROM (lv_index_table) INTO TABLE <lt_indx_table> UP TO 1000 ROWS.
LOOP AT <lt_indx_table> ASSIGNING <lwa_indx_table>.
ASSIGN COMPONENT 'EXTID' OF STRUCTURE <lwa_indx_table> TO FIELD-SYMBOL(<lv_extid>).
ASSIGN COMPONENT 'MTRCT' OF STRUCTURE <lwa_indx_table> TO FIELD-SYMBOL(<lv_mtrct>).
ASSIGN COMPONENT 'MSKVL' OF STRUCTURE <lwa_indx_table> TO FIELD-SYMBOL(<lv_mskvl>).
CHECK <lv_extid> IS ASSIGNED AND <lv_mtrct> IS ASSIGNED AND <lv_mskvl> IS ASSIGNED.
CONCATENATE <lv_extid> '_' <lv_mtrct> INTO <lv_mskvl>.
ENDLOOP.
MODIFY (lv_index_table) FROM table <lt_indx_table>.
There are different solutions for your requirement. It depends your number of records, your system, database etc.
If you have really huge data try cursors.
You can process data in packages. That's not increase performance pretty much but it helps prevention of performance deterioration.
For detailed information check this links (1 , 2, 3).
DATA s_cursor TYPE cursor.
DATA:it_mara TYPE TABLE OF mara.
OPEN CURSOR WITH HOLD s_cursor FOR
SELECT * FROM mara.
DO.
FETCH NEXT CURSOR s_cursor APPENDING TABLE it_mara PACKAGE SIZE 10.
IF sy-subrc <> 0.
EXIT.
ENDIF.
"Your logic should be here..
"If you want to update database use CALL FUNCTION 'DB_COMMIT'
ENDDO.
CLOSE CURSOR s_cursor.

PostgreSQL: return row where any column value like variable

I am trying to have the user search for a value in a SQL table, and the user is returned with any row that contains that value. At the moment, I can make it work such that the code is:
SELECT * FROM table WHERE lower('foo') in (lower('col1'),lower('col2'),etc)
However, I would like it to be able to search every column and return any row LIKE 'foo'. For instance,
SELECT * FROM table WHERE (lower('col1'), lower('col2'), etc) like lower('%foo%')
But that doesn't work.
Any suggestions?
I believe you need to use multiple WHERE clauses instead of grouping them all into one statement. Try this:
SELECT * FROM table
WHERE lower(col1) like lower('%foo%')
OR lower(col2) like lower('%foo%')
OR etc like lower('%foo%')
You can convert the whole row to a string and then use LIKE on the result of that:
select *
from the_table
where lower(the_table::text) like '%foo%';
the_table::text returns all columns of each row as a comma separated list enclosed with parentheses, e.g. (42,Arthur,Dent). So the above is not 100 identical to a LIKE condition applied on each column - but probably does what you want.

From which table does for all enteries makes a select?

I have two standard tables, VBAP and MAKT.
I want elements of MAKT-MAKTX, where MAKT-MATNR = VBAP - MATNR.
SELECT MATNR FROM VBAP INTO IT_VBAP.
SELECT MATNR MAKTX FROM MAKT INTO IT_MAKT FOR ALL ENTRIES WHERE MATNR = IT_VBAP.
Does this code choose values in it_makt where only those matnr fields are equal?
What exactly does for all entries does.
Thank you.
select field_1 field_2 field_n from table into internal_table for all
entries in another_internal_table where some_field_in_table = another_internal_table-same_field_in_another_internal_table.
You use for all entries when you want to fill an internal table according to values in another internal table.
You can try using the following
select matnr from vbap into it_vbap.
select maktx from makt into it_makt for all entries in it_vbap where matnr = it_vbap-matnr.
For all entries is the the exact thing, You might think, as You read it. It is like this:
"For all entries in" allows You to use a subset of an internal table as where condition in a select statement by the possibility to provide the fields of this internal table as where condition-parameters in the select statement.
So, internally it is also only a loop, You can use the sql-monitor transaction, and mostly will see, that for all entries really behaves like a select inside a loop if I remember correctly. It is quite helpful, and usually used relatively often.
If the subset-table, which is used as parameter-table is empty, then You perform a full table select (full table scan), if You only use the tables fields as where parameters. So always pay attention to the select which fills Your where-table or check its contents with if lines( the_table ) > 0. Nevertheless take a look at vwegert's link, it describes the pros and cons of for all entries. Do You need more info ?

Forcing a datatype in MS Access make table query

I have a query in MS Access which creates a table from two subqueries. For two of the columns being created, I'm dividing one column from the first subquery into a column from the second subquery.
The datatype of the first column is a double; the datatype of the second column is decimal, with scale of 2, but I want the second column to be a double as well.
Is there a way to force the datatype when creating a table through a standard make-table Access query?
One way to do it is to explicitly create the table before putting anything into it.
Your current statement is probably like this:
SELECT Persons.LastName,Orders.OrderNo
INTO Persons_Order_Backup
FROM Persons
INNER JOIN Orders
ON Persons.P_Id=Orders.P_Id
WHERE FirstName = 'Alistair'
But you can also do this:
----Create NewTable
CREATE TABLE NewTable(FirstName VARCHAR(100), LastName VARCHAR(100), Total DOUBLE)
----INSERT INTO NewTableusing SELECT
INSERT INTO NewTable(FirstName, LastName, Total)
SELECT FirstName, LastName,
FROM Person p
INNER JOIN Orders o
ON p.P_Id = o.P_Id
WHERE p.FirstName = 'Alistair'
This way you have total control over the column types. You can always drop the table later if you need to recreate it.
You can use the cast to FLOAT function CDBL() but, somewhat bizarrely, the Access Database Engine cannot handle the NULL value, so you must handle this yourself e.g.
SELECT first_column,
IIF(second_column IS NULL, NULL, CDBL(second_column))
AS second_column_as_float
INTO Table666
FROM MyTest;
...but you're going to need to ALTER TABLE to add your keys, constraints, etc. Better to simply CREATE TABLE first then use INSERT INTO..SELECT to populate it.
You can use CDbl around the columns.
An easy way to do this is to create an empty table with the correct field types and then to an Append-To query and Access will automatically convert the data to the destination field.
I had a similar situation, but I had a make-table query creating a field with NUMERIC datatype that I wanted to be short text.
What I did (and I got the idea from Stack) is to create the table with the field in question as Short Text, and at the same time build a delete query to scrub the records. I think it's funny that a DELETE query in access doesn't delete the table, just the records in it - I guess you have to use a DROP TABLE function for that, to purge a table...
Then, I converted my make-table query to an APPEND query, which I'd never done before... and I just added the running of the DELETE query to my process.
Thank you, Stack Overflow !
Steve
I add a '& ""' to the field I want to make sure are stored as text, and a ' *1 ' (as in multiplying the amount by 1) to the fields I want to store as numeric.
Seems to do the trick.
To get an Access query to create a table with three numeric output fields from input numeric fields, (it kept wanting to make the output fields text fields), had to combine several of the above suggestions. Pre-establish an empty output table with pre-defined output fields as integer, double and double. In the append query itself, multiply the numeric fields by one. It worked. Finally.