Calling one procedure from another procedure - oracle

The code below is saved in a file named proc1.sql
DECLARE
B VARCHAR2(25);
C NUMBER;
PROCEDURE Get_manager_detailS(NO IN NUMBER,NAME OUT VARCHAR2,SAL1 OUT NUMBER)
IS
BEGIN
SELECT ENAME, SAL
INTO NAME, SAL1
FROM EMP
WHERE EMPNO = NO;
END;
BEGIN
Get_manager_detailS(7900,B,C);
DBMS_OUTPUT.PUT_LINE(B);
DBMS_OUTPUT.PUT_LINE(C);
END;
/
This procedure is stored in another file proc3.sql
PROCEDURE Test_Procedure()
IS
BEGIN
b varchar2(25);
c number;
DBMS_OUTPUT.PUT_LINE('CALLING');
Get_manager_details(7900,b,c);
END;
When I am running it in sqlplus, it is showing an error
SP2-0734 UNKNOWN COMMAND BEGINING PROCEDURE.. REST OF THE LINES IGNORED.
SP2-0042 UNKNOWN COMMAND" IS "..REST OF THE LINE IGNORED.

Creating a PROCEDURE/FUNCTION vs. ANONYMOUS BLOCK
Stored PROCEDURES/FUNCTIONS always starts with CREATE OR REPLACE ... and ends with END;
CREATE OR REPLACE serves as the implicit declare for stored functions and procedures, thus you dont have to write DECLARE anymore inside the block
An anonymous block starts with DECLARE and ends with END;
As for the code/block of codes saved in proc1.sql.
Your declaration is misplaced.You should place it after the end of
the procedure
Start the procedure with CREATE OR REPLACE PROCEDURE
Try This Block:
-- DECLARE
-- B VARCHAR2(25);
-- C NUMBER;
CREATE OR REPLACE PROCEDURE Get_manager_detailS(NO IN NUMBER,
NAME OUT VARCHAR2,
SAL1 OUT NUMBER)
IS
BEGIN
SELECT ENAME, SAL
INTO NAME, SAL1
FROM EMP
WHERE EMPNO = NO;
END; -- end of procedure
/
DECLARE -- start of anonymous block
B VARCHAR2(25);
C NUMBER;
BEGIN
Get_manager_detailS(7900,B,C);
DBMS_OUTPUT.PUT_LINE(B);
DBMS_OUTPUT.PUT_LINE(C);
END;
As for the procedure that will call the get_manager_details procedure.Its will be just the same as the anonymous block, the only difference will be is that it is stored
Base from what have you done already
If you will not declare parameters in your procedure, parenthesis are not necessary so remove it.
If you dont have output parameters that will catch the result of your procedure, you can use dbms_output.put_line as you have used in
the anonymous block above
variable declarations should be done after the IS keyword and before BEGIN statements, because as I have noted above CREATE OR
REPLACE ... IS is the implicit declare for the stored functions and
procedures
TRY THIS:
CREATE OR REPLACE PROCEDURE Test_Procedure
IS -- always start with CREATE OR REPLACE
b varchar2(25);
c number;
BEGIN
-- b varchar2(25); misplaced declarations
-- c number;
DBMS_OUTPUT.PUT_LINE('CALLING');
Get_manager_details(7900,b,c);
DBMS_OUTPUT.PUT_LINE(B); -- displays the results b
DBMS_OUTPUT.PUT_LINE(C); -- and c
END;
Sorry for the long post.
HOPE THIS HELPS.
CHEERS

Your first block is anonymous block in which you declare procedure - you can call procedure Get_manager_details within anonymous block only. You can't call Get_manager_details from Test_Procedure because there is no such procedure. You need to create your procedure Get_manager_details first
Create or replace procedure Get_manager_details ....
Then you can run
Create or replace procedure Test_Procedure ....
Or it will not compile.

If you are trying to call the procedure get_manager_details inside test_procedure then you first need to create the test procedure.
Add create or replace procedure test_procedure .
Then after creating the test_procedure you can execute it in an anonymous block which will call the get_manager_details procedure.

Related

PLS-00306: wrong number or types of arguments in call to procedure PROC_T

declare
TYPE stag_tab IS TABLE OF d_staging%ROWTYPE;
stag_tab1 stag_tab;
begin
--Bulk Collect
select * bulk collect into staging_tab1 from d_staging;
PKG_T.PROC_T(stag_tab1);
end;
/
Package definition:
--Package
CREATE OR REPLACE PACKAGE PKG_T
AS
TYPE staging IS TABLE OF d_staging%ROWTYPE;
PROCEDURE PROC_T(p_staging IN staging);
END PKG_T;
/
-- Package Body
CREATE OR REPLACE PACKAGE BODY PKG_T
AS
PROCEDURE PROC_T (p_staging IN staging)
AS
VAR1 d_staging%ROWTYPE;
CUR1 SYS_REFCURSOR;
QUERY_STRING VARCHAR2(2000);
BEGIN
OPEN CUR1 FOR SELECT * from table(p_staging);
LOOP
FETCH CUR1 into VAR1;
EXIT WHEN cur1%NOTFOUND;
INSERT into d (testdata) VALUES (var1.testval1);
COMMIT;
END LOOP;
END;
END PKG_T;
/
You are receiving the error because the procedure PKG_T.PROC_T is expecting a parameter of type staging, but when you are calling the procedure you are passing it a variable of type stag_tab. The type of the variable being passed to the procedure needs to match the type of the parameter definition for the procedure.
Your procedure declaration:
PROCEDURE PROC_T (p_staging IN staging)
Takes the argument as type staging.
You are passing the argument as a locally defined type:
TYPE stag_tab IS TABLE OF d_staging%ROWTYPE;
These are different types. Instead, you need the PL/SQL block to be:
declare
stag_tab1 package_name.staging;
begin
select *
bulk collect into stag_tab1
from d_staging;
PKG_T.PROC_T(stag_tab1);
end;
/

PL SQL Procedure from Trigger

I created procedure GETDEL that select name from students , but when i try to call this procedure in trigger it says i gave wrong types of argument to call
I have been trying to pass (records) or (records OUT SYS_REFCURSOR) as a argument but it dont works
CREATE OR REPLACE PROCEDURE GETDEL(records OUT SYS_REFCURSOR) AS
BEGIN
OPEN records FOR
SELECT name FROM students;
END GETDEL;
CREATE OR REPLACE TRIGGER After_delete_student
AFTER DELETE ON TABLE2
FOR EACH ROW
DECLARE
rec sys_refcursor;
BEGIN
GETDELCZL();
END;
Your procedure contains a single parameter and, even though it's an out parameter, the calling procedure is responsible the defining it.
create or replace
trigger after_delete_student
after delete
on table2
for each row
declare
result_rec sys_refcursor;
begin
getdel(result_rec);
end;

How can I call stored procedure within a procedure and print the output in same line?

How can I call a stored procedure within a procedure and print the output in same line.
For example my full name is 'Alex Bob' and I have created 2 procedure each for firstname(p1) and lastname(p2) like this:
-- Procedure 1:
CREATE OR REPLACE PROCEDURE p1(fn in out varchar)
IS
BEGIN
dbms_output.put_line(fn);
END;
-- Procedure 2:
CREATE OR REPLACE PROCEDURE p2(ln in out varchar)
IS
BEGIN
p1('Alex');
dbms_output.put_line(ln);
END;
-- Calling procedure
exec p2('Bob');
Now this will give me output like this:
Alex
Bob
But I want to print name together (in a single line) and for this I tried calling procedure within procedure by creating local variable and calling procedure & storing returned value in that variable. Here is my revised code:
CREATE OR REPLACE PROCEDURE p1(fn in varchar)
IS
BEGIN
declare
cn varchar;
cn := exec p2('Bob');
dbms_output.put_line(fn || cn);
END;
CREATE OR REPLACE PROCEDURE p2(ln in out varchar)
IS
BEGIN
ln := ln;
END;
exec p1('Alex');
but this doesn't work as expected. How can I achieve this ?
You can create a Private Procedure to achieve this. See below:
CREATE OR REPLACE PROCEDURE p1 (fn IN VARCHAR)
AS
v_nam varchar2(100):='Bob';
--private Procedure
PROCEDURE p2 (LN IN OUT VARCHAR)
IS
BEGIN
null;
END;
BEGIN
p2(lN => v_nam);
DBMS_OUTPUT.put_line (fn ||' '||v_nam);
END;
Execution:
SQL> exec p1('Alex');
Alex Bob
PL/SQL procedure successfully completed.
First of all, literals cannot be passed as in OUT parameters - only IN, simply because you cannot assign anything to a literal, can you? Now back to the problem at hand. If you need those two procedures be able to print on the same line, use dbms_output.put() in all procedures but the last one and in the last one call dbms_output.put_line(). here is an example:
CREATE OR REPLACE PROCEDURE p1(fn in varchar2)
IS
BEGIN
dbms_output.put(fn);
END;
/
-- Procedure 2:
CREATE OR REPLACE PROCEDURE p2(ln in varchar2)
IS
BEGIN
p1('Alex ');
dbms_output.put(ln);
END;
/
create or replace procedure p3(ln in varchar2)
is
begin
p2('Bob ');
dbms_output.put_line(ln);
end;
exec p3('is a nice guy')
Result:
Alex Bob is a nice guy
PL/SQL procedure successfully completed
Find out more

Calling a stored PROCEDURE in Toad

I have a defined a new stored procedure but get a error while calling it,
CREATE OR REPLACE PROCEDURE SCOTT.getempsal(
p_emp_id IN NUMBER,
p_emp_month IN CHAR,
p_emp_sal OUT INTEGER)
AS
BEGIN
SELECT EMP_SAL
INTO p_emp_sal
FROM EMPLOYEE_SAL
WHERE EMP_ID = p_emp_id
AND EMP_MONTH = p_emp_month;
END getempsal;
And trying to call it:
getempsal(1,'JAN',OUT) --Invalid sql statement.
Your procedure contains an out parameter, so you need to call it in block like:
declare
a number;
begin
getempsal(1,'JAN',a);
dbms_output.put_line(a);
end;
A simple procedure (let's say with a number parameter) can be called with
exec proc(1);
or
begin
proc(1);
end;
Just write EXECUTE procedure_name('provide_the_valueof_IN parameter','value of in parameter', :k) ;
Run this statement a popup will come set the parameters as in out and the datatype too. U will see the output in another popup window.

Variable from an procedure to the parameter of another procedure

Using a package, how can i pass a variable assign in a procedure to the parameter of another procedure?
I'm not sure if you are wondering about global variables or how OUT parameters work. An example of using a procedure's OUT parameter is below. More info on using IN and OUT can be found here
create or replace package TEST_PKG
IS
procedure test(p_input IN NUMBER, p_output OUT NUMBER)
IS
BEGIN
p_output := p_input * p_input;
END test ;
procedure testRun
IS
v_input NUMBER := 0;
v_output NUMBER;
BEGIN
test(v_input, v_output);
DBMS_OUTPUT.PUT_LINE('OUTPUT : ' || v_output );
END test ;
END xyz;
create or replace package xyz
IS
procedure test
IS
v_temp varchar2(20); --local variable
BEGIN
v_temp:=20; --assigning value to a variable
--if procedure is within the same package,as this example shows ,then call as below
test2(v_temp);
--if procedure is in another package say PQR then call as below,
--but the procedure should be declared in the specification of the package PQR
PQR.test2(v_temp);
--if procedure is not inside any package ,just a single procedure is there
--,then call as below
test2(v_temp);
END test ;
procedure test2(p_temp IN varchar2)
IS
BEGIN
--do you processing
END test2;
END xyz;
Hope this helps

Resources