Call a stored procedure with another in Oracle - sql

Does anyone know of a way, or even if its possible, to call a stored procedure from within another? If so, how would you do it?
Here is my test code:
SET SERVEROUTPUT ON;
DROP PROCEDURE test_sp_1;
DROP PROCEDURE test_sp;
CREATE PROCEDURE test_sp
AS
BEGIN
DBMS_OUTPUT.PUT_LINE('Test works');
END;
/
CREATE PROCEDURE test_sp_1
AS
BEGIN
DBMS_OUTPUT.PUT_LINE('Testing');
test_sp;
END;
/
CALL test_sp_1;

Your stored procedures work as coded. The problem is with the last line, it is unable to invoke either of your stored procedures.
Three choices in SQL*Plus are: call, exec, and an anoymous PL/SQL block.
call appears to be a SQL keyword, and is documented in the SQL Reference. http://download.oracle.com/docs/cd/B19306_01/server.102/b14200/statements_4008.htm#BABDEHHG The syntax diagram indicates that parentesis are required, even when no arguments are passed to the call routine.
CALL test_sp_1();
An anonymous PL/SQL block is PL/SQL that is not inside a named procedure, function, trigger, etc. It can be used to call your procedure.
BEGIN
test_sp_1;
END;
/
Exec is a SQL*Plus command that is a shortcut for the above anonymous block. EXEC <procedure_name> will be passed to the DB server as BEGIN <procedure_name>; END;
Full example:
SQL> SET SERVEROUTPUT ON
SQL> CREATE OR REPLACE PROCEDURE test_sp
2 AS
3 BEGIN
4 DBMS_OUTPUT.PUT_LINE('Test works');
5 END;
6 /
Procedure created.
SQL> CREATE OR REPLACE PROCEDURE test_sp_1
2 AS
3 BEGIN
4 DBMS_OUTPUT.PUT_LINE('Testing');
5 test_sp;
6 END;
7 /
Procedure created.
SQL> CALL test_sp_1();
Testing
Test works
Call completed.
SQL> exec test_sp_1
Testing
Test works
PL/SQL procedure successfully completed.
SQL> begin
2 test_sp_1;
3 end;
4 /
Testing
Test works
PL/SQL procedure successfully completed.
SQL>

Sure, you just call it from within the SP, there's no special syntax.
Ex:
PROCEDURE some_sp
AS
BEGIN
some_other_sp('parm1', 10, 20.42);
END;
If the procedure is in a different schema than the one the executing procedure is in, you need to prefix it with schema name.
PROCEDURE some_sp
AS
BEGIN
other_schema.some_other_sp('parm1', 10, 20.42);
END;

#Michael Lockwood - you don't need to use the keyword "CALL" anywhere. You just need to mention the procedure call directly.
That is
Begin
proc1(input1, input2);
end;
/
instead of
Begin
call proc1(input1, input2);
end;
/

To invoke the procedure from the SQLPlus command line, try one of these:
CALL test_sp_1();
EXEC test_sp_1

Calling one procedure from another procedure:
One for a normal procedure:
CREATE OR REPLACE SP_1() AS
BEGIN
/* BODY */
END SP_1;
Calling procedure SP_1 from SP_2:
CREATE OR REPLACE SP_2() AS
BEGIN
/* CALL PROCEDURE SP_1 */
SP_1();
END SP_2;
Call a procedure with REFCURSOR or output cursor:
CREATE OR REPLACE SP_1
(
oCurSp1 OUT SYS_REFCURSOR
) AS
BEGIN
/*BODY */
END SP_1;
Call the procedure SP_1 which will return the REFCURSOR as an output parameter
CREATE OR REPLACE SP_2
(
oCurSp2 OUT SYS_REFCURSOR
) AS `enter code here`
BEGIN
/* CALL PROCEDURE SP_1 WITH REF CURSOR AS OUTPUT PARAMETER */
SP_1(oCurSp2);
END SP_2;

Related

How to declare variables in procedure in PL/SQL

In PL/SQL I have learned that there are two ways to define procedures like below.
Method 1
DECLARE
a number;
PROCEDURE print(mynum number) IS
BEGIN
dbms_output.put_line(mynum);
END;
Method 2
CREATE print(mynum number) IS
BEGIN
dbms_output.print_line(mynum);
END;
But only in method 2, the procedure will store in DBMS as we can call it again and again. What is the difference between two different methods of creating a PLSQL procedure and how we can create and save the store procedure in DBMS which consists of declared variables?
Although you posted invalid syntax, OK - I think I understand the question.
If you want the procedure to be stored, you have to use what you called "Method 2", e.g.
create or replace procedure print (mynum number) is
a number; --> locally declared variable
begin
a := mynum * mynum;
dbms_output.put_line(mynum);
dbms_output.put_line(a);
end;
/
The first piece of code ("Method 1") represents an anonymous PL/SQL block whose contents is "lost" at the end of your session (i.e. when you disconnect).

Call Cursor located in different procedure

I have a rather complex cursor located in a stored procedure that I'm going to need in a different procedure. Is it bad practice to just copy and paste the cursor in this procedure? Could I just call that cursor sort of like this?
OPEN diffProcedure.cursorName(params)...
LOOP
FETCH ....
INTO ....
EXIT WHEN ....
END LOOP;
The cursor is probably 200 lines of complicated code which I don't have a good understanding of (Junior Dev working on complicated business PL/SQL code), but I know what it does. Calling it with the parameters I need will get the correct data needed.
Is it a bad idea to just copy the cursor from one procedure to another? Could I call the cursor from a different procedure?
You cannot reference a cursor declared in a procedure from another procedure.
But when you declare a cursor in the package, you can call it from other procedures located in the same package, in other packages, and even from standalone procedures.
Simple example:
CREATE OR REPLACE PACKAGE somepackage IS
CURSOR my_cursor( par IN NUMBER ) IS
SELECT par FROM dual;
END;
/
CREATE OR REPLACE PACKAGE someotherpackage IS
PROCEDURE MY_Procedure;
END;
/
CREATE OR REPLACE PACKAGE BODY someotherpackage IS
PROCEDURE MY_Procedure IS
x NUMBER;
BEGIN
OPEN somepackage.my_cursor( 2 );
FETCH somepackage.my_cursor INTO x;
CLOSE somepackage.my_cursor;
DBMS_OUTPUT.PUT_LINE( x );
END;
END;
/
create or replace procedure some_standalone_procedure IS
y NUMBER;
BEGIN
OPEN somepackage.my_cursor( 5 );
FETCH somepackage.my_cursor INTO y;
CLOSE somepackage.my_cursor;
DBMS_OUTPUT.PUT_LINE( y );
END;
/
and now fire tests:
exec someotherpackage.MY_Procedure;
2
exec some_standalone_procedure;
5

Calling a stored procedure with a select

I have a query and i have to put it in a stored procedure but when I call the stored procedure it doesn´t return anything;
This is my query:
select * from mdc_cat_parametros where param_llave='SMTP_SERVER';
When I execute the query it returns one row but the stored procedure doesn´t.
This is my stored procedure:
CREATE OR REPLACE PROCEDURE MDC_UTIL_PROCEDURE
AS
RT MDC_CAT_PARAMETROS%ROWTYPE;
BEGIN
SELECT * INTO RT FROM MDC_CAT_PARAMETROS WHERE PARAM_LLAVE='SMTP_SERVER';
END MDC_UTIL_PROCEDURE;
I call the stored procedure:
EXECUTE MDC_UTIL_PROCEDURE;
The stored procedure is populating RT but you then need to select out of it:
CREATE OR REPLACE PROCEDURE MDC_UTIL_PROCEDURE (results OUT SYS_REFCURSOR)
AS
RT MDC_CAT_PARAMETROS%ROWTYPE;
BEGIN
SELECT * INTO RT FROM MDC_CAT_PARAMETROS WHERE PARAM_LLAVE='SMTP_SERVER';
OPEN results FOR SELECT * FROM RT;
END MDC_UTIL_PROCEDURE;
or you could simplify it to get rid of the RT variable:
CREATE OR REPLACE PROCEDURE MDC_UTIL_PROCEDURE (results OUT SYS_REFCURSOR)
AS
BEGIN
OPEN results FOR
SELECT * FROM MDC_CAT_PARAMETROS WHERE PARAM_LLAVE='SMTP_SERVER';
END MDC_UTIL_PROCEDURE;
Your procedure is just fetching the result set into a local variable in the procedure. When the procedure exits, the variable is no longer in scope. If you want to return data from a select, you need to use a ref cursor. Here is a link to some good examples

Use value of stored procedure in another stored procedure in PLSQL

Is there any way of calling a stored procedure from another stored procedure, and use retrieved value (from the second procedure) back in the first one?
-- procedure #1
create or replace procedure Proc1(p_RetValue out SomeDataType)
is
begin
-- any logic goes here
p_retValue := 5+5; -- for example. Let's assume that the SomeDataType is number;
end;
-- second procedure
create or replace procedure Proc2 is
l_variable number;
begin
Proc1(l_variable); -- the value 10 will be assigned to l_variable;
end;

Call stored procedure from sqlplus

How to call a stored procedure from sqlplus?
I have a procedure:
Create or replace procedure testproc(parameter1 in varachar2,parameter2 out varchar2)
begin
Do something
end;
I tried exec testproc(12,89) ::Returns error
The second parameter of your procedure is an OUT parameter -- its value will be assigned to the variable passed when the procedure completes. So you can't use a literal value for this parameter.
You can declare a bind variable at the SQLPlus prompt and use that:
-- Declare bind variable
VARIABLE x NUMBER
-- If necessary, initialize the value of x; in your example this should be unnecessary
-- since the value of the second parameter is never read
EXEC :x := 1
-- Call the procedure
EXEC testproc(12, :x)
-- Print the value assigned to the bind variable
PRINT x
Alternatively, you can use an anonymous PL/SQL block:
-- Activate client processing of dbms_output buffer
SET SERVEROUTPUT ON
-- In anonymous block, declare variable, call procedure, print resulting value
DECLARE
x NUMBER;
BEGIN
testproc(12, x);
dbms_output.put_line( x );
END;
/
create or replace procedure autogenerate(t1 in int,t2 in int)
is
jum number;
begin
if t1 < 10 then
dbms_output.put_line('Value too low.');
else if t1 > 20 then
dbms_output.put_line('Value too high.');
end if;
end if;
end;
/
show errors;
set serveroutput on;
execute autogenerate(1,2);
Try this, if you have question just post it again to me :)