Default parameter in oracle procedure - oracle

I have created a package xyz like follows :-
create or replace package xyz
is
procedure abc( v_frst_param in VARCHAR2 default 'Y')
IS
BEGIN
dbms_output.put_line(v_frst_param);
-- CALLING another function
update_table(p_frst_parm =>v_frst_param,
p_second_param =>'2');
END;
In the dbms_output.put_line the output is coming null when i am not passing any value while calling abc procedure.
if i have passed default and i am not passign any parameter shouldnt the value come as Y in the ouput

First of all, I think that package would be invalid, you are trying to add a body for your function in your package specification. However the whole idea is good and it should be working, if done right, for example, create a package:
create or replace package xyz is
procedure abc(v_frst_param in varchar2 default 'Y');
procedure abc(v_frst_param in varchar2 default 'Y', v_second_param in varchar2);
end xyz;
And a package body:
create or replace package body xyz is
procedure abc(v_frst_param in varchar2 default 'Y') is
begin
dbms_output.put_line(v_frst_param);
end;
procedure abc(v_frst_param in varchar2 default 'Y', v_second_param in varchar2) is
begin
dbms_output.put_line(v_frst_param || ' / ' || v_second_param);
end;
end xyz;
Then you may want to make the call of your procedure:
begin
xyz.abc;
xyz.abc(); -- This is the same thing as above
xyz.abc(v_second_param => 'Maybe');
end;
Please note that if you send anything as a parameter for v_first_parameter to that procedure, it will use the value you sent and not the default one.

Try this out
Mostly depends on how you are calling your procedure -ABC(); or ABC; or ABC(NULL); or ABC(''); and the way your parameters are declared.
Create or replace procedure ABC(v_frst_param IN VARCHAR2 Default 'Y')
AS
OUT_v_frst_param VARCHAR2(100);
BEGIN
OUT_v_frst_param := v_frst_param ;
dbms_output.put_line('The PROCEDURE OUTPUT is : ' || OUT_v_frst_param );
END;
--Procedure created.
BEGIN
ABC(); --calling procedure
END;
The PROCEDURE OUTPUT is : Y
Statement processed.
Now if you call your procedure like:
BEGIN
ABC; --calling procedure
END;
The PROCEDURE OUTPUT is : Y
Statement processed.
--passing `NULL`
BEGIN
ABC(NULL);
END;
The PROCEDURE OUTPUT is :
Statement processed.
-- Passing again ''
BEGIN
ABC('');
END;
The PROCEDURE OUTPUT is :
Statement processed.
--passing text
BEGIN
ABC('hello world');
END;
The PROCEDURE OUTPUT is : hello world
Statement processed.

Related

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

How can a stored procedure be executed in Oracle with in and out parameters?

Here's my stored procedure:
CREATE OR REPLACE PROCEDURE STATS_SD
(
P_ID IN NUMBER,
PRC OUT SYS_REFCURSOR
)
IS
BEGIN
OPEN PRC FOR
SELECT
ID,
SESID
FROM RESPONSES
WHERE ID IN (P_ID)
END;
When I try to execute it using
EXEC EXAM_STATS_STUDENTS_SD('6901');
I get the following error:
PLS-00306: wrong number or types of arguments in call to 'STATS_SD'
Do you have any ideas why?
Here is an example using an OUT parameter that is a sys_refcursor. Note that I close the cursor in the pl/sql block that uses it (which is important!):
create or replace procedure get_data(o_cur OUT SYS_REFCURSOR) as
begin
OPEN o_cur FOR
select * from emp;
end;
And using the get_data procedure:
declare
l_cur sys_refcursor;
l_row emp%rowtype;
begin
get_data(l_cur);
LOOP
fetch l_cur
into l_row;
exit when l_cur%notfound;
-- do something with l_row here
END LOOP;
close l_cur;
end;
You are passing a wrong datatype to your procedure.
According to your declaration a NUMBER is expected:
P_ID IN NUMBER
However, you pass a VARCHAR2 in your exec command:
EXEC EXAM_STATS_STUDENTS_SD('6901');
Note the '' around the value.
Try calling this instead:
EXEC EXAM_STATS_STUDENTS_SD(6901);
Apart from that you are missing the second parameter completely.

referencing a variable from another procedure in plsql

I have written a package :
CREATE OR REPLACE
PACKAGE BODY NEW_HIRE_PKG
AS
PROCEDURE load_emp(
errbuf OUT VARCHAR2,
retcode OUT VARCHAR2 )
AS
CURSOR cur_person_info
IS
SELECT * FROM table_abc;
CURSOR cur_person_adr
IS
SELECT * FROM table_adr;
l_person_id NUMBER;
l_emp_num NUMBER;
lv_add_type VARCHAR2(100);
lv_address_line1 VARCHAR2(100);
BEGIN
FOR person_info_rec IN cur_address_info
LOOP
hr_employee_api.create_employee ( p_validate => FALSE,
--INPUT Parameter
P_HIRE_DATE =>person_info_rec.DATE_START,
-- output
p_employee_number => lc_employee_number, p_person_id => ln_person_id );
END LOOP ;
END;
PROCEDURE load_add(
errbuf OUT VARCHAR2,
retcode OUT VARCHAR2 )
as
ln_person_id number;
BEGIN
FOR address_info_rec IN cur_address_info
LOOP
BEGIN
hr_person_address_api.create_person_address
(p_validate => FALSE,
p_effective_date => TRUNC(SYSDATE),
p_person_id=> ln_person_id,
--output
p_address_type => lv_add_type,
p_address_line1 => lv_address_line1);
end;
end loop;
end;
end;
Now in the procedure the load_add there is a variable ln_person_id which should be the person ids generated in the procedure load_emp. I want to pass it in this procedure one by one. Can i do it by making ln_person_id an object ?
Judging by your code you have two concurrent programs - one that calls load_emp() and one that calls load_add(). If that's really the structure you want then the two calls will run in separate sessions and there's nothing you can do to pass a variable from one to the other. The best you could do would be to hold all the person_id values from load_emp in a custom table. The data could then later be consumed by load_add().
However I would restructure your package. Why not call load_add() from within the LOOP in load_emp() ?

Calling one procedure from another procedure

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.

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