I need to recreate some SAP stored procedures in Oracle. I've been trying to find tutorials, similar questions, examples, etc about this but apparently no one had to do this before
What Oracle SQL query can be similar to this SAP query ?
SELECT * FROM A
INTO CORRESPONDING FIELDS OF TABLE B
FOR ALL ENTRIES IN C
WHERE a = C-a
AND x = y.
LOOP AT B INTO D.
D-b = E-b.
INSERT c FROM D.
IF SY-SUBRC <> 0.
WRITE: / 'error on insert', D-b, D-a.
ENDIF.
Any help will be appreciated, Thanks.
I recommend you to use transaction 'ST05' to trace your program. This tool will show details of the queries on the database including the exact SQL executed.
EDIT:
As a demonstration of the queries generated by SAP for Oracle let's execute this code and trace it with transaction 'ST05'. Remember to run 'ST05' before executing the program.
tables: mara.
data: it_mara type standard table of mara,
it_eina type standard table of eina.
select-options so_matnr for mara-matnr.
start-of-selection.
select matnr from mara into corresponding fields of table it_mara
up to 100 rows where matnr in so_matnr.
check sy-subrc eq 0.
select * from eina into table it_eina for all entries in it_mara
where matnr eq it_mara-matnr.
After execution check the output in transaction 'ST05':
If you want more details select an SQL statement in the screen and then click the button 'Explain'. You will see the following:
For better reference on transaction 'ST05' check this link.
Hope it helps.
The FOR ALL ENTRIES statement usually produces many queries which results are then grouped by UNION or UNION ALL.
Here is a really nice analysis for Microsoft SQL Server.
Because of the fact that UNION and UNION ALL are part of SQL standard I think it is implemented exactly the same for any other SQL database.
[EDIT]
As Mr Miranda stated it looks differently when it comes to Oracle database. I googled a bit and found this article where it is said that IN-LISTs are used which seems also to be plausible.
Related
I'm running Apex 19.2 and I would like to create a classical or interactive report based on dynamic query.
The query I'm using is not known at design time. It depends on an page item value.
-- So I have a function that generates the SQL as follows
GetSQLQuery(:P1_MyItem);
This function may return something like
select Field1 from Table1
or
Select field1,field2 from Table1 inner join Table2 on ...
So it's not a sql query always with the same number of columns. It's completely variable.
I tried using PL/SQL function Body returning SQL Query but it seems like Apex needs to parse the query at design time.
Has anyone an idea how to solve that please ?
Cheers,
Thanks.
Enable the Use Generic Column Names option, as Koen said.
Then set Generic Column Count to the upper bound of the number of columns the query might return.
If you need dynamic column headers too, go to the region attributes and set Type (under Heading) to the appropriate value. PL/SQL Function Body is the most flexible and powerful option, but it's also the most work. Just make sure you return the correct number of headings as per the query.
How can I use a plsql code block like this with an Interactive Grid (Using Oracle Apex) :
begin
Query A;
exception when no_data_found then
Query B;
end;
Actually sometimes 'Query A' returns nothing and I want to run 'Query B'. any solution?
An interactive grid has to use a sql-query as source.
a. Write one query and use sql-query as source:
SELECT * FROM A
UNION ALL
SELECT * FROM B WHERE COUNT(SELECT * FROM A) = 0;
b. Write some function which does the work
Read this:
How to return a resultset / cursor from a Oracle PL/SQL anonymous block that executes Dynamic SQL?
But it sounds a little bit strange, that you got one grid for two datasources. This will bring up some problems when manipulating the data.
Open questions
Do you want to modify the data?
Do you want to insert new rows?
Does the user understand what's going on and what he is seeing?
Since there is no apparent way to NOT use an SQL query as the Interactive Grid source, you could maybe (depending on your specific solution) think differently and create an Interactive Grid region for each query. Then you could show one or another when the page loads, using a region server-side condition or even a Dynamic Action.
To expand on other answers with a little specificity, since this is about managing results of 2 different queries, you can put the 2 different queries in 2 different Grid regions. Then on the first region add a Server-side Condition of "Rows returned" and copy the SQL Query into the query input provided. On the 2nd region, you would set "No Rows returned" condition and again copy Query 1 into the SQL input provided.
I am a SQL Server guy and just started working on Netezza, one thing pops up to me is a daily query to find out the size of a table filtered out by year: 2016,2015, 2014, ...
What I am using now is something like below and it works for me, but I wonder if there is a better way to do it:
select count(1)
from table
where extract(year from datacolumn) = 2016
extract is a built-in function, applying a function on a table with size like 10 billion+ is not imaginable in SQL Server to my knowledge.
Thank you for your advice.
The only problem i see with the query is the where clause which executes a function on the 'variable' side. That effectively disables zonemaps and thus forces netezza to scan all data pages, not only those with data from that year.
Instead write something like:
select count(1)
from table
where datecolumn between '2016-01-01' and '2016-12-31'
A more generic alternative is to create a 'date dimension table' with one row per day in your tables (and a couple of years into the future)
This is an example for Postgres: https://medium.com/#duffn/creating-a-date-dimension-table-in-postgresql-af3f8e2941ac
This enables you to write code like this:
Select count(1)
From table t join d_date d on t.datecolumn=d.date_actual
Where year_actual=2016
You may not have the generate_series() function on your system, but a 'select row_number()...' can do the same trick. A download is available here: https://www.ibm.com/developerworks/community/wikis/basic/anonymous/api/wiki/76c5f285-8577-4848-b1f3-167b8225e847/page/44d502dd-5a70-4db8-b8ee-6bbffcb32f00/attachment/6cb02340-a342-42e6-8953-aa01cbb10275/media/generate_series.tgz
A couple of further notices in 'date interval' where clauses:
Those columns are the most likely candidate for a zonemaps optimization. Add a 'organize on (datecolumn)' at the bottom of your table DDL and organize your table. That will cause netezza to move around records to pages with similar dates, and the query times will be better.
Furthermore you should ensure that the 'distribute on' clause for the table results in an even distribution across data slices of the table is big. The execution of the query will never be faster than the slowest dataslice.
I hope this helps
I'm using Oracle APEX 5.0 and I'm trying to built a classic report with custom search based on more than one criteria like (From Date, To Date, Serial And Emp Name(Selected from List and returns ID)), I wrote the Conditions Like :
where emp_id = nvl(:P73_EMP_ID,emp_id)
or ror_serial like nvl('%'||:P73_SERIAL||'%',ror_serial)`
or ror_effective_date between to_date(:P73_FROM_DATE) and to_date(:P73_TO_DATE)
and ror_approved_flag = 'N'
The problem is that I need The search based on one or more Criteria, That means I may left some items empty, and if all the items are empty, I need the whole records to be shown, Thanks For help.
There are two ways to do this:
1. "Quick and Dirty" way
This is fine as long as you are dealing with small data sets where performance will not be an issue.
Simply allow for nulls in your conditions e.g.
and (:P73_FROM_DATE is null or ror_effective_date >= to_date(:P73_FROM_DATE))
and (:P73_FROM_DATE is null or ror_effective_date <= to_date(:P73_TO_DATE))
and so on.
2. Dynamic SQL
This is better for larger data sets where performance could be an issue.
Change the report source type to "PL/SQL function returning SQL query".
Then change the source to look like this
declare
q long;
begin
-- The query with any conditions always applied
q := 'select a, b, c from mytable where ror_approved_flag = ''N''';
-- Append any optional conditions
if :P73_FROM_DATE is not null then
q := q || ' and ror_effective_date >= to_date(:P73_FROM_DATE)';
end if;
-- etc.
return q;
end;
This will result in an appropriate query being generated based on the criteria you have. This means that Oracle can choose the most appropriate query plan for the criteria.
Interactive report can be the way. You can filter and use multiple filters. You can save reports too. It meets all your requirements with minimal sql knowledge.
Don't know how complicated your query can bee but if you need to change syntax of your query then only way is prepare statement with some pl/sql logic.
Also look at sample apps like P-Track in APEX page 35 - Milestones it can give you some ideas to prepare the rest.
such as:
select country
from table1
inner join table2 on table1.id=table2.id
where table1.name='a' and table2.name='b'
group by country
after the parse, which part will be executed first?
It looks like you want to know the execution plan chosen by Oracle. You can get that ouput from Oracle itself:
set serveroutput off
< your query with hint "/*+ gather_plan_statistics */" inserted after SELECT >
select * from table(dbms_xplan.display_cursor(null, null, 'last allstats'));
See here for an explanation how to read a query plan: http://download.oracle.com/docs/cd/E11882_01/server.112/e16638/ex_plan.htm#i16971
Be aware however that the choice of a query plan is not fixed. Oracle tries to find the currently best query plan, based on available statistics data.
There are plenty of places you can find the order in which SQL is executed:
FROM clause
WHERE clause
GROUP BY clause
HAVING clause
SELECT clause
ORDER BY clause
But note that this is the "theoretical" order - SQL engines are allowed to perform the operations in other orders, provided that the end result appears to have been produced by using the above order.
If you install the free tool SQL*Developer from Oracle, then you can click a button to get the explain plan.
A quick explanation is at http://www.seeingwithc.org/sqltuning.html