What means the statement "Select ... for all Entries ..." - select

I was trying to do select for all entries in select statement - abap. I'm not getting the clear idea what select for entries does. Does any one know ?
Kindly have a look at the statements below:
1.
select bukrs belnr xblnr budat
from bkpf
into table it_bkpf
where belnr in s_belnr
2.
select bukrs belnr buzei gsber zuonr wrbtr kunnr
from bseg
into table it_bseg
for all entries in it_bkpf
where belnr = it_bkpf-belnr.
Please let me know the difference in two statements.
Siva

Some obvious differences:
Different tables
Different target fields
The 2nd select had a syntax problem: You used form instead from (I corrected it with my edit)
Other differences:
The selection 1.) uses in in the where clause. So it uses a select-options (or a range-object).
for all entries in it_bkpf means, that the internal table it_bkpf contains a list of elements, you want to select. Or in other words: Select all entries in bseg, where a filed belnr is an element of hte internal table bseg.

You will get clear answer through ST05 transaction.
You could execute st05 transaction, choose trace SQL and activate
trace.
After that run your code.
Enter st05 again choose deactivate trace, then view trace result.
There you can see exact SQL code that is forwarded to database server. As BSEG is clustered table, you could not use intuitive header-item join to retrieve needed financial movements inforamation. It's just because there are several tables including BSEG are storing in single database table, so database server technically can not separate BSEG rows and find BSEG-specific fields to make proper join.
So you can do join-like construction at application server. First you are retrieving all header-related columns from header table ( BKPF). Next when SELECT ... FOR ALL ENTRIES IN ... is executed application server will take a little portions of header rows (typically 5) and construct SQL queries for retrieving packs of items, corresponding to that portions. Next all that portions will merged in single internal table. So there will be only items of desired document as it were if you could execute normal join.

Here's what happens the way I understand it. The two statements are probably executed after another:
The first statement selects a few entries from the bkpf table. These entries are stored in the internal table it_bkpf (say belnr 1, 2, 3).
Each of these entries is then used as part of the select #2. The "for all entries" matches the belnr in table bseg to those in the internal table it_bkpf from the first statement. The matching entries are then put into the internal table it_bseg.
With the example you've given this is pretty much the same if the where clause in SQL #2 was where belnr in s_belnr (instead of the whole for all entries). This would only make sense if you needed the contents of it_bkpf for some other purpose. Another typical situation is if you determine the contents of the internal table used in the for all entries clause with some program logic instead of reading it directly from the database.
One catch with "for all entries": Make sure the internal table in the for all entries is not empty - then the whole table in the from clause would be selected.

Related

How to perform same SQL query on many tables using FOR IN LOOP statement?

I am just starting with functions and it seems like I went a bit over my head with this one)
So for example I need to execute SELECT * FROM <table> query. I need this query to be executed for all tables I have.
And list of table names is just another table, so to get all table names I have to execute SELECT table_names FROM meta_table_info
How can I do this for many tables using some sort of cycle?
Thank you beforehand.

Common table expression,WITH clause in PostgreSQL ;ERROR: relation "stkpos" does not exist

for example the following is my query
WITH stkpos as (
select * from mytbl
),
updt as (
update stkpos set field=(select sum(fieldn) from stkpos)
)
select * from stkpos
ERROR: relation "stkpos" does not exist
Unlike MS-SQL and some other DBs, PostgreSQL's CTE terms are not treated like a view. They're more like an implicit temp table - they get materialized, the planner can't push filters down into them or pull filters up out of them, etc.
One consequence of this is that you can't update them, because they're a copy of the original data, not just a view of it. You'll need to find another way to do what you want.
If you want help with that you'll need to post a new question that has a clear and self contained example (with create table statements, etc) showing a cut down version of your real problem. Enough to actually let us understand what you're trying to accomplish and why.

Postgres/GIS: RULE does not affect all inserts

I have a rule for a table which simply checks if the new entry matches a name and intersects with that matching existing row using st_intersects from postgis library.
It seems that only a part are NOT inserted, but most get through this rule. I checked some entries manually after the insert and can confirm the rule should have blocked that insert.
Is something wrong with my RULE?
Table has 3 columns. id serial, name varchar(200) and way geometry(Linestring,4326)
And my RULE is as follows (excerpt from \d names)
blockduplicate AS
ON INSERT TO nameslist
WHERE (EXISTS ( SELECT 1
FROM nameslist
WHERE nameslist.name::text = new.name::text AND st_intersects(nameslist.way, new.way) = true)) DO INSTEAD NOTHING
This table simply takes a line having a name, and whenever another entry comes in with the same name and intersecting with another existing entry having the same name, it should be blocked. So I have only one entry with this name in the area represented by the geometry field way. After the insert I see plenty of duplicates (name matches and st_intersects returns true when checking way field). Why is my rule not blocking the insert?
Update: Is it because I do multiple inserts in one query. I actually insert 12000 entries in one shot with the query INSERT INTO (a,b,c) VALUES (...),(...),(...),...
Does PostgreSQL call the RULE for each value? I need to do multiple inserts otherwise it would take months to finish my inserts.
Ok, usually you are going to find triggers are cleaner than rules. Triggers are fired on each insert. Rules are macros which rewrite your SQL. There is a time and place for the use of rules but they are certainly an advanced area.
Let's look at what happens with your insert. Suppose you:
INSERT INTO nameslist
SELECT * FROM nameslist_import;
Your rule will actually rewrite the query into something like:
INSERT INTO nameslist
SELECT * FROM nameslist_import WHERE not (expression modelled on your rule);
Usually it is cleaner here to just write this into your query rather than using a rule to rewrite your query for you. This allows you to tune exactly what you want to do in each query. If you want to prevent such data from overlapping, look at exclude constraints if they are applicable or triggers.
Hope this helps.

Postgresql, query results to new table

Windows/NET/ODBC
I would like to get query results to new table on some handy way which I can see through data adapter but I can't find a way to do it.
There is no much examples around to satisfy beginner's level on this.
Don't know temporary or not but after seeing results that table is no more needed so I can delete it 'by hand' or it can be deleted automatically.
This is what I try:
mCmd = New OdbcCommand("CREATE TEMP TABLE temp1 ON COMMIT DROP AS " & _
"SELECT dtbl_id, name, mystr, myint, myouble FROM " & myTable & " " & _
"WHERE myFlag='1' ORDER BY dtbl_id", mCon)
n = mCmd.ExecuteNonQuery
This run's without error and in 'n' I get correct number of matched rows!!
But with pgAdmin I don't see those table no where?? No matter if I look under opened transaction or after transaction is closed.
Second, should I define columns for temp1 table first or they can be made automatically based on query results (that would be nice!).
Please minimal example to illustrate me what to do based on upper code to get new table filled with query results.
A shorter way to do the same thing your current code does is with CREATE TEMPORARY TABLE AS SELECT ... . See the entry for CREATE TABLE AS in the manual.
Temporary tables are not visible outside the session ("connection") that created them, they're intended as a temporary location for data that the session will use in later queries. If you want a created table to be accessible from other sessions, don't use a TEMPORARY table.
Maybe you want UNLOGGED (9.2 or newer) for data that's generated and doesn't need to be durable, but must be visible to other sessions?
See related: Is there a way to access temporary tables of other sessions in PostgreSQL?

Insert and update records in one TSQL statement?

I have a table BigTable and a table LittleTable. I want to move a copy of some records from BigTable into LittleTable and then (for these records) set BigTable.ExportedFlag to T (indicating that a copy of the record has been moved to little table).
Is there any way to do this in one statement?
I know I can do a transaction to:
moves the records from big table based on a where clause
updates big table setting exported to T based on this same where clause.
I've also looked into a MERGE statement, which does not seem quite right, because I don't want to change values in little table, just move records to little table.
I've looked into an OUTPUT clause after the update statement but can't find a useful example. I don't understand why Pinal Dave is using Inserted.ID, Inserted.TEXTVal, Deleted.ID, Deleted.TEXTVal instead of Updated.TextVal. Is the update considered an insertion or deletion?
I found this post TSQL: UPDATE with INSERT INTO SELECT FROM saying "AFAIK, you cannot update two different tables with a single sql statement."
Is there a clean single statement to do this? I am looking for a correct, maintainable SQL statement. Do I have to wrap two statements in a single transaction?
You can use the OUTPUT clause as long as LittleTable meets the requirements to be the target of an OUTPUT ... INTO
UPDATE BigTable
SET ExportedFlag = 'T'
OUTPUT inserted.Col1, inserted.Col2 INTO LittleTable(Col1,Col2)
WHERE <some_criteria>
It makes no difference if you use INSERTED or DELETED. The only column it will be different for is the one you are updating (deleted.ExportedFlag has the before value and inserted.ExportedFlag will be T)