I want to use HQL:
select u,
call some_procedure(m.id)
from User u
some_procedure is an Oracle stored procedure. Is it possible to use stored procedure inside of Select HQL-Statement?
Calling functions that are unknown to Hibernate can be done by using the FUNCTION wrapper: select u, FUNCTION('some_procedure', u.id) from User u but that won't work because Hibernate doesn't know how to materialize the result of the function. You will have to wrap a cast around: select u, cast(FUNCTION('some_procedure', u.id) as String) from User u
Related
I have the function below
CREATE OR REPLACE FUNCTION BUTCE_REPORT_Fun (birim_id IN VARCHAR2)
RETURN sys_refcursor
IS
retval sys_refcursor;
BEGIN
OPEN retval FOR
select *
from ifsapp.butce_gerceklesme
WHERE budget_year = '2018'
AND USER_GROUP = birim_id ;
RETURN retval;
END BUTCE_REPORT_Fun;
and am trying to execute the function this way
SELECT * from table(IFSAPP.BUTCE_REPORT_FUN('3008'))
the line above generates this exception
ora-22905 cannot access rows from a non-nested table item
to keep in mind that ifsapp.butce_gerceklesme is a view (which I do not think that it matters).
So how I can solve this. any help is appreciated.
Actually, am trying to create a function that returns rows from the view above according to the parameters provided. so if I can achieve that in another way that would be better.
Ref Cursors are for use in program calls: they map to JDBC or ODBC ResultSet classes. They can't be used as an input to a table() call. Besides, there is no value in calling your function in SQL because you can simply execute the embedded query in SQL.
the main table is huge and the inner query assigned to USER_GROUP is selected every time
So maybe what you want is subquery factoring AKA the WITH clause?
with ug as (
select con2.CODE_PART_VALUE
from IFSAPP.ACCOUNTING_ATTRIBUTE_CON2 con2
where COMPANY = 'XYZ'
and ATTRIBUTE = 'ABC'
and CODE_PART = 'J'
and con2.ATTRIBUTE_VALUE=407
AND rownum = 1
)
select *
from ifsapp.butce_gerceklesme t
join ug on t.USER_GROUP = ug.CODE_PART_VALUE
WHERE t.budget_year = '2018'
Tuning queries on StackOverflow is a mug's game, because there are so many things which might be responsible for sub-optimal performance. But as a rule of thumb you should try to tune the whole query. Encapsulating a part of it in PL/SQL is unlikely to improve response times, and indeed may degrade them.
How create procedure e.g.:
Create PROCEDURE il_klub as (
select
sum(krk.kluby_id),
r.nazwa
FROM
rozgrywki_klubowe r,
kluby_roz_klub krk
WHERE
r.id = krk.rozgrywki_klubowe_id
GROUP by r.nazwa
)
and function e.g.:
DECLARE #mistrz TABLE (nazwa varchar, rozgrywki varchar)
INSER INTO #mistrz (nazwa, rozgrywki)
select
k.nazwa, r.nazwa
from
kluby k,
rozgrywki_klubowe r,
kluby_roz_klub krk,
historia_roz_klub hrk,
where
k.id = krk.kluby_id and k.id = hrk.kluby_id and r.id = krk.rozgrywki_klubowe_id
and r.id = hrk.rozgrywki_klubowe_id
and hrk.miejsce =1 and r.system like 'ligowy'
Select * from #mistrz
In Oracle SQL Data Modeler
The syntax for a procedure declaration is
CREATE OR REPLACE PROCEDURE IL_KLUB AS
vSUM_KLUBY KLUBY_ROZ_KLUB%TYPE;
vNAZWA ROZGRYWKI_KNUBOWE.NAZWA%TYPE;
BEGIN
select sum(krk.kluby_id),
r.nazwa
INTO vSUM_KLUBY,
vNAZWA
FROM rozgrywki_klubowe r,
kluby_roz_klub krk
WHERE r.id = krk.rozgrywki_klubowe_id
GROUP by r.nazwa;
END IL_KLUB;
This procedure is, obviously, not particularly useful as it doesn't do anything with the results of the SELECT, and that will probably draw a compilation warning. But that's how you declare it.
A function is defined in similar fashion, but you also need to define a return type, and then return a value:
CREATE OR REPLACE FUNCTION IL_KLUB_NAZWA
RETURN ROZGRYWKI_KNUBOWE.NAZWA%TYPE
AS
vSUM_KLUBY KLUBY_ROZ_KLUB%TYPE;
vNAZWA ROZGRYWKI_KNUBOWE.NAZWA%TYPE;
BEGIN
select sum(krk.kluby_id),
r.nazwa
INTO vSUM_KLUBY,
vNAZWA
FROM rozgrywki_klubowe r,
kluby_roz_klub krk
WHERE r.id = krk.rozgrywki_klubowe_id
GROUP by r.nazwa;
RETURN vNAZWA;
END IL_KLUB_NAZWA;
Oracle PL/SQL Language Reference here
Oracle SQL Language Reference here
Best of luck.
I have a refcursor in a function, declared like this:
my_cursor type_refcur_my
And populated as such:
OPEN my_cursor FOR
SELECT DISTINCT A.vegetable, A.animal, A.mineral, A.ID,
(SELECT DISTINCT SUBSTR(bcptr.bcptr_desc_l1,INSTR(bcptr.bcptr_desc_l1,')',-1)-3,3)
FROM doe D, ray R, me M
WHERE ...) ID
FROM artifacts A
ORDER BY vegetable, mineral;
RETURN my_cursor;
I need to perform an operation that involves another SELECT on all the rows in the recursor and use some logic to alter 2 of the column values before returning it. Something kind of like:
IF my_cursor.vegetable = (SELECT B.ID from vegetables B
WHERE my_cursor.vegetable = B.vegetable_description)
THEN
my_cursor.A.ID := B.ID
END IF;
My thought was to put this code after opening the cursor and before returning it. But this produces compile errors, and I cannot find an appropriate example online.I appreciate your help.
Just looking if there is any way to have the following behaviuour.
Currently I'm doing
select * from table_1 t1 where function_call(t1.col1, t1.col2) <> 0;
The reason why I'm calling the function function_call is , The function has the table table_2 which I don't have access. The only way I can access is through one package.
Is there any way changing the above behaviour to, having the table information in the from clause instead of calling the function_call in where clause.
like ,
select * from table_1 t1, package_x.get_table_2() where t1.col1 = 1 and t1.col2 = 1 and t1.col3 = t2.col3
I agree that calling a function from the WHERE clause may result in slow performance as this will very likely result in a full table scan of TABLE_1, with the function being called once for every row in TABLE_1. I can think of several things your site can do:
Grant the necessary level of access to TABLE_1.
Create a view on TABLE_1 which restricts the data which can be seen, and grant appropriate access on the view, or
Live with the slow access times.
Share and enjoy.
I dont want to use the "loop" related keyword, how can I implement loop with basic sql command in oracle ?
I have two table :
A:
ID, Color
B,
ID, AID, Type
I want to loop all records in B, and if ID = AID, then set the A.Color = B.Type
Thanks in advance !
Looping is, by definition, a procedural construct.
SQL is declarative: tell the database what you want done, not how to do it.
If you're absolutely convinced that you need to program such a thing, then write it in PL/SQL, Oracle's procedural language.
Bu I'm sure that it's possible to do what you want in SQL using an UPDATE with a WHERE clause.
Something like this (corrected per NullUserException):
UPDATE A SET A.Color = (SELECT B.Type FROM B WHERE A.ID = B.AID)
An alternate method:
MERGE INTO a
USING b
ON (b.aid = a.id)
WHEN MATCHED THEN UPDATE SET a.color = b.type;
You could just do:
UPDATE tablea a
SET a.color = (SELECT b.type
FROM tableb b
WHERE b.aid = a.id)
See this SQL script.
To do that you will have to write a stored procedure using PL/SQL. Here is the oracle page with some info and papers on the topic.
As others pointed out, you can probably solve your problem with a normal DML statement, without any looping involved. But to give you some basics on how to accomplish what you asked for in PL/SQL, here's an example...
DECLARE
CURSOR c IS
SELECT id, aid, type FROM b;
statement VARCHAR2(200);
BEGIN
FOR iterator IN c LOOP
IF iterator.id = iterator.aid THEN
statement := 'UPDATE a SET color = ' || iterator.type || 'WHERE id = ' || iterator.id;
EXECUTE IMMEDIATE statement;
END IF;
END LOOP;
END;
This anonymous PL/SQL block will iterate through each record in table b, and if b.id = b.aid, it will update table a and set a.color = b.type where a.id = b.id.
This seems to be what you were asking for. It's not exactly an efficient way to go about doing things, since you're firing off one DML statement per row in table b that has b.id=b.aid. But I wanted more to give this as a syntax example. This is just one way to iterate through a cursor by the way; you can also explicitly open cursors and fetch records, but it's easier this way if you don't need to do anything but iterate over the entire result set.