Calling a Procedure in Select Statement - oracle

I have a package consists of function and procedures
CREATE OR REPLACE PACKAGE BODY schema.pkg_product as
function xxxxx()
procedure product_get(p_product_id IN Number,
P_direct_balance Out Number,
P_indirect_balance Out Number) IS
v_request CLOB :=<soapenv:Envelope xmnlns:----->
v request_end varchar(100) := <can:----->
BEGIN
Selct statement
END
My question is can we can Call the procedure in the select statement and how can I get the P_direct_balance , P_indirect_balance. if so in the select query coz I want to retrieve that data from the procedure.

It's not possible. You could write a function but you cannot use functions with out parameters in SQL. So you'll have to rewrite your code. For instance create two functions that return p_direct_balance and p_indirect_balance.

If rewriting the procedure to be a function with an out parameter is not possible, I would suggest altering the procedure to write the relevant values to a temporary table and commit. Then use your select statement to retrieve the values from the temp table.

Related

To pass collection to Stored procedure call as input without using the variable

I have a requirement where we have to call a oracle Stored Procedure which has collection type as input parameter.
So my stored procedure is like:
Create or replace package test
As
Type t is table of varchar(400) index by binary_integer.
Procedure testprc(p_client_id in number,t_no in number,t1 in t,t2 in t);
End;
Create or replace package body test
As
Procedure testprc(p_client_id in number,t_no in number,t1 in t, t2 in t)
is
Begin
for i in 1 ..tno loop
Insert into client
(Client_id,Client_phone,client_email) values (p_client_id,t1(i),t2(i));
End loop;
End;
End;
Now in the call to this stored procedure testprc.test I don't want to create a variable of type t and pass it to the stored procedure instead I want to directly pass the list of values to the SP.
Something like this
Exec testprc(13,1,{1=>'22737371'},{1=>'test#abc.com'}).
Is there any way I can achieve this.
If you are on 18c or higher, you can use a qualified expression to avoid having to create a temporary variable to hold associative arrays. For example:
SQL> exec test.testprc(13,1,test.t(1=>'22737371'),test.t(1=>'test#abc.com'))
PL/SQL procedure successfully completed.

Using DECODE in PL/SQL procedure call

I have a stored PL/SQL procedure (say X) that inserts records into a table. I am calling that procedure from another procedure (say Y). I have some parameters in procedure Y like para1,para2,para3 which can have two values either zero or one, for zero and one values I have one id stored in a TBL_SETUP, and when I call procedure X I want to check that if para1 is null then return null, if it is not null then check if it is one then return YES_ID and if it is no then return NO_ID.
I have tried something like this. I wrote a SELECT statement for getting YES_ID,NO_ID before calling the procedure and it is working fine, but when I write procedure call as below, it is giving me error "PLS-00204: Function or pseudo-column may be used inside a SQL statement only". How to use DECODE in a procedure call?
PROC_X(DECODE(para1,NULL,NULL,DECODE(para1,'1',YES_ID,NO_ID)),para2,NULL,NULL,DECODE(para2,'1',YES_ID,NO_ID)),para3,NULL,NULL,DECODE(para3,'1',YES_ID,NO_ID)),)
You could use SELECT INTO:
DECLARE
DECODE_RESULT VARCHAR2(100); -- or any suitable data type
BEGIN
SELECT DECODE(...) INTO DECODE_RESULT FROM dual;
PROC_X(DECODE_RESULT);
END;

ORACLE - Selecting Parameters for calling Procedure from Table

Is it possible to select the parameters for calling a procedure from the select statement?
EXECUTE PROCEDURE_NAME(para1,para2,para3,para4);
commit;
Is it possible to select para1,para2,para3,para4 from a select query?
EXECUTE PROCEDURE_NAME((SELECT PARA1,PARA2,PARA3,PARA4 FROM TABLEA))
COMMIT;
I do not have access to modify the procedure.
As a slight variation on what #vc74 suggested, you could just replace your EXECUTE command (which, assuming this is SQL*Plus or SQL Developer anyway, is just a wrapper for an anonymous block anyway) with an explicit anonymous block:
begin
for r in (SELECT PARA1,PARA2,PARA3,PARA4 FROM TABLEA) loop
PROCEDURE_NAME(r.PARA1,r.PARA2,r.PARA3,r.PARA4);
end loop;
end;
/
(I've left the bits from your original call uppercase and the new bits lower case mostly to distinguish them.)
Using a loop just means you don't need to declare local variables and select into those. It would also allow you to process multiple rows from the table, though I see form a comment you only expect one row. However, the flip side of that is it won't complain if there are no rows, or if there is more than one row, as the variable approach would do.
You could also use a record type to avoid declaring all the parameters separately:
declare
l_row tablea%rowtype;
begin
SELECT * into l_row FROM TABLEA;
PROCEDURE_NAME(l_row.PARA1,l_row.PARA2,l_row.PARA3,l_row.PARA4);
end;
/
This now does expect exactly one row to be found in the table.
You can call the functions in sql. So if you are able to create a function in your schema then you can do the following:
create a function function_name in your schema that calls the procedure procedure_name and returns some dummy result
use this function in sql query: select function_name(para1,para2,para3,para4) from tablea
example of function:
create or replace function function_name(
p1 varchar2,
p2 varchra2,
p3 varchar2,
p4 varchar2
) return number
is
begin
procedure_name(p1,p2,p3,p4); -- here you execute the procedure
return null;
end;

How to pass a variable to a query in Oracle stored procedure?

I wrote a simple oracle stored procedure to fetch some data using a SYS_REFCURSOR. In my query I have a WHERE clause. I want to pass a parameter to the where clause. Here what I tried,
CREATE OR REPLACE PROCEDURE GETCUSTOMER(customer_code IN CUSTOMER.CUSTOMER_CODE%TYPE, customer_names OUT SYS_REFCURSOR)
IS
BEGIN
OPEN customer_names FOR
SELECT
*
FROM CUSTOMER
WHERE CUSTOMER_CODE = customer_code;
END;
/
I executed this using spring jdbcTemplate. This is not working as expected. This fetches all the data in the CUSTOMER table.
Is there a special way to pass a parameter in to a WHERE clause? How may I fix this?
Just prefix the variable with the procedure name.
CREATE OR REPLACE PROCEDURE GETCUSTOMER(customer_code IN CUSTOMER.CUSTOMER_CODE%TYPE, customer_names OUT SYS_REFCURSOR)
IS
BEGIN
OPEN customer_names FOR
SELECT
*
FROM CUSTOMER
WHERE CUSTOMER_CODE = GETCUSTOMER.customer_code;
END;
/

Oracle equivalent of stored procedure that returns an inline table?

Example in T-SQL (SQL Server - taken from here):
CREATE PROC proc_authors
#au_lname VARCHAR(40)
AS
SELECT
au_id, au_fname, au_lname, city, state
FROM authors
WHERE au_lname = #au_lname
go
Is it possible in Oracle to create a stored procedure that returns an inline table (without declaring a type - like the above)? If not, what would be the closest alternative? i.e. declare inline type, then use it. The idea is to minimize number of DB permissions that are granted.
Please include sample code as part of your answer.
Reasoning behind using stored procedure vs function - we have legacy software that can only execute stored procedures, or raw queries. It appears that only stored procedures in there have support for parameterized execution, which is what we are after.
try this with ref cursor
PROCEDURE proc_get_tada(ip_user IN VARCHAR2,
op_error_code OUT NUMBER,
op_cursor OUT SYS_REFCURSOR,) AS
BEGIN
OPEN op_cursor FOR
SELECT * FROM your_table yt where yt.user = ip_user;
EXCEPTION
WHEN OTHERS THEN
op_error_code := -1;
END proc_get_tada;
you will get collection of all data from you table you can iterate in java or calling program.
Maybe you are searching for something like this:
create table author
(
au_id number,
au_name varchar2(100)
);
insert into author (au_id, au_name) values(1, 'ME');
create or replace function getAuthor(auName varchar2)
return author%rowtype
is
retval author%rowtype;
begin
select * into retval from author where au_name=auName;
return retval;
end;
declare
auth author%rowtype;
begin
auth := getAuthor('ME');
dbms_output.put_line(auth.au_id);
end;

Resources