How to achive PLSQL procedure overloading package - plsql

I have a use case where a package has 2 procedure with the same name and argument, one as CHAR type and another is VARCHAR2 type.
How to call tham?

For PL/SQL the package spec and body compiles ok.
But at runtime the 2 procedures are the same and there is no way to distinguish because CHAR type and VARCHAR2 type are of the same datatype family.
For example:
create or replace package pk_over
is
procedure pr_text(p_isbCaracter char);
procedure pr_text(p_isbCaracter varchar2);
End;
create or replace package body pk_over
is
procedure pr_text(p_isbCaracter char)
is
Begin
Dbms_Output.Put_Line('Soy PR_TEXT parĂ¡metro CHAR="'||p_isbCaracter||chr(34));
End pr_text;
--
procedure pr_text(p_isbCaracter varchar2)
is
Begin
Dbms_Output.Put_Line('Soy PR_TEXT parĂ¡metro VARCHAR2="'||p_isbCaracter||chr(34));
End pr_text;
--
End pk_over;
An you call with:
Declare
sbVar2 varchar2(20);
Begin
sbVar2:='Texto 1';
pk_over.pr_text(sbVar2);
End;
The error at runtime is:
PLS-00307: too many declarations of 'PR_TEXT' match this call
So you don't need the 2 procedures, only one.

Related

PLS-00221: 'JOBSTAB' is not a procedure or is undefined

I'm currently studying PL/SQL and was doing experiment by declaring a private PL/SQL in the package index-by table called jobs_tab_type that should be indexed by a string type based on the jobs.job_id%type.
Now I really don't want to put it in a package right away and just test it first so first I created it in an anonymous block.
DECLARE
TYPE jobs_tab_type IS TABLE OF jobs%rowtype INDEX BY jobs.job_id%type;
jobstab jobs_tab_type;
BEGIN
for rec in(select job_id from jobs)
LOOP
jobstab(rec.job_id);
END LOOP;
END;
I compiled it and ran into this error 'PLS-00221: 'JOBSTAB' is not a procedure or is undefined .
I don't know what i did wrong based on the documentations i'm currently reading online. But I don't get what is wrong, i didn't even declared a constraint and just referenced it with the data type that is on the database.
Update:
This is the description of my jobs table:
I changed the following code to:
DECLARE
TYPE jobs_tab_type IS TABLE OF jobs%rowtype INDEX BY jobs.job_id%type;
jobstab jobs_tab_type;
BEGIN
for rec in(select job_id from jobs)
LOOP
jobstab(rec.job_id) := rec;
END LOOP;
END;

How to pass bind variable as IN OUT parameter in PLSQL procedure

I want to use 1st parameter of my procedure EMP_ID as IN OUT parameter. Originally it's IN parameter and this procedure is working fine, but as the last line concern
htp.p('Inserted for Employee-id '||EMP_ID);
I want to use this line in anonymous block and most importantly it should be a bind variable because I am creating the REST API in which user will only enter values and it will be taken as bind variable in oracle Apex and the below procedure is working fine with respect of IN parameter.
create or replace procedure att_time_ins (EMP_ID in varchar2, ORG_ID in number,V_TIME_STATUS in number) is
BEGIN
INSERT INTO TIME_ATTENDANCE_POOL
(EMPLOYEE_ID, ATTENDANCE_DATE,TIME_HOURS,TIME_MINUTES,TIME_STATUS,LOCATION_ID,ORG_ID,PREPARED_ON )
VALUES
(EMP_ID, to_date(sysdate,'DD/MM/YYYY'),to_char(sysdate,'HH24') ,to_char(sysdate,'MI'),V_TIME_STATUS,null,ORG_ID,
to_date(sysdate,'DD/MM/YYYY') );
COMMIT;
time_management.create_attendance_sheet(v_org_id => ORG_ID,
v_employee_id => EMP_ID,
target_date => to_date(sysdate,'DD/MM/YYYY'));
htp.p('Inserted for Employee-id '||EMP_ID);
end att_time_ins;
I am calling my procedure in this way
begin
att_time_ins(:employee_id,:org_id,:time_status);
end;
Please help me to modify this stuff according to IN OUT Parameter i.e Employee_id should be IN OUT parameter. There is no proper documentation regarding passing bind variables as in out prameter in PLSQL Block.
Let us say you have a procedure named PR_PROC, you can use VARIABLE statement for passing IN OUT or OUT kind of variables.
CREATE OR REPLACE PROCEDURE PR_PROC (EMP_NAME IN VARCHAR2,
EMP_ID IN OUT VARCHAR2)
IS
BEGIN
DBMS_OUTPUT.PUT_LINE (EMP_NAME||EMP_ID);
END;
VARIABLE KURSOR VARCHAR2
BEGIN
:KURSOR:='4';
PR_PROC('SENIOR',:KURSOR);
END;
Note: If you are using TOAD Editor you can press F5 to make it work.
Oracle VARIABLE

PL/SQL: Use parameters within execute immediate

I have a function like this (unfortunately, I cannot change it to send one array instead of multiple parameters):
CREATE FUNCTION (p1_ IN OUT VARCHAR2(100), p2_ IN OUT VARCHAR2(100), <...>, p10_ IN OUT VARCHAR2(100)
IS
BEGIN
gather_value(p1_);
gather_value(p2_);
<...>
gather_value(p8_);
END;
To clean it up a little bit, I would prefer to change the body as follows:
IS
stmt VARCHAR2(1000);
BEGIN
FOR i IN 1 .. 8
LOOP
stmt := 'gather_value(p:1_);'
EXECUTE IMMEDIATE stmt USING i;
END LOOP;
END;
However, in that case no such parameters are found.
Is there a way to work it around?

retrieve recordset with more than one column value using refcursor in oracle

am creating a package in pl/sql . with in this i declared the ref cursor . With in procedure am using select statement with multiple column name . but am not able to get the result.
here i attached my code. Help me to correct the error. Am new to pl/sql
code
CREATE OR REPLACE PACKAGE types AS
TYPE cursor_type IS REF CURSOR;
END Types;
/
CREATE OR REPLACE
PROCEDURE get_CDR_rs (p_no IN zkv.FLD_callingPartyNumber%TYPE,
CDR_recordset OUT SYS_REFCURSOR) AS
BEGIN
OPEN CDR_recordset FOR
SELECT FLD_callingPartyNumber,
FLD_dateTimeConnect
FROM CISCOCUIC_TBL
WHERE FLD_callingPartyNumber= p_no
ORDER BY FLD_callingPartyNumber,;
END get_CDR_rs;
/
SET SERVEROUTPUT ON SIZE 1000000
DECLARE
l_cursor SYS_REFCURSOR;
l_callingPartyNumber zkv.FLD_callingPartyNumber%TYPE;
l_dateTimeConnect zkv.FLD_dateTimeConnect%TYPE;
BEGIN
LOOP
FETCH l_cursor
INTO l_callingPartyNumber, l_dateTimeConnect;
EXIT WHEN l_cursor%NOTFOUND;
END LOOP;
CLOSE l_cursor;
END;
/
Error
9/41 PL/SQL: ORA-00936: missing expression
5/5 PL/SQL: SQL Statement ignored
First thing is there is a syntax error in the procedure. It should be
CREATE OR REPLACE
PROCEDURE get_CDR_rs (p_no IN zkv.FLD_callingPartyNumber%TYPE,
CDR_recordset OUT SYS_REFCURSOR) AS
BEGIN
OPEN CDR_recordset FOR
SELECT FLD_callingPartyNumber,
FLD_dateTimeConnect
FROM CISCOCUIC_TBL
WHERE FLD_callingPartyNumber= p_no
ORDER BY FLD_callingPartyNumber; -- there was a comma which is not required or you
-- missed a column
END get_CDR_rs;
/
Secondly where is get_CDR_rs being called to retrieve the results?
Thirdly why do you need the following? because you are using sys_refcursor
CREATE OR REPLACE PACKAGE types AS
TYPE cursor_type IS REF CURSOR;
END Types;
/
If you would like to see the results of your procedure which returns sys_refcursor, do as follows
variable rset refcursor;
DECLARE
p_no zkv.FLD_callingPartyNumber%TYPE;
BEGIN
p_no := '123';
get_CDR_rs (p_no, :rset);
END;
/
print rset

Oracle 11g PL/SQL Positions of CONTANT variables in PACKAGE

I have strictly optimization problem. where in my PACKAGE I should place CONSTANT variables when procedure/function is being called many times ?
Let's look at this:
CREATE OR REPLACE PACKAGE WB_TEST IS
PROCEDURE TEST;
END WB_TEST;
CREATE OR REPLACE PACKAGE BODY WB_TEST IS
FUNCTION PARSER(IN_PARAM IN VARCHAR2) RETURN VARCHAR2 IS
LC_MSG CONSTANT VARCHAR2(80) := 'Hello USERNAME! How are you today?';
LC_PARAM CONSTANT VARCHAR2(10) := 'USERNAME';
BEGIN
RETURN REPLACE(LC_MSG, LC_PARAM, IN_PARAM);
END PARSER;
PROCEDURE TEST IS
BEGIN
FOR I IN 1 .. 1000 LOOP
DBMS_OUTPUT.PUT_LINE(PARSER(TO_CHAR(I)));
END LOOP;
END TEST;
BEGIN
DBMS_OUTPUT.ENABLE(1000000);
END WB_TEST;
/
Or is better to do something like that:
CREATE OR REPLACE PACKAGE WB_TEST IS
PROCEDURE TEST;
END WB_TEST;
CREATE OR REPLACE PACKAGE BODY WB_TEST IS
GC_MSG CONSTANT VARCHAR2(80) := 'Hello USERNAME! How are you today?';
GC_PARAM CONSTANT VARCHAR2(10) := 'USERNAME';
FUNCTION PARSER(IN_PARAM IN VARCHAR2) RETURN VARCHAR2 IS
BEGIN
RETURN REPLACE(GC_MSG, GC_PARAM, IN_PARAM);
END PARSER;
PROCEDURE TEST IS
BEGIN
FOR I IN 1 .. 1000 LOOP
DBMS_OUTPUT.PUT_LINE(PARSER(TO_CHAR(I)));
END LOOP;
END TEST;
BEGIN
DBMS_OUTPUT.ENABLE(1000000);
END WB_TEST;
It is extremely unlikely to matter from a performance standpoint. The code the PL/SQL compiler generates should be identical in both cases-- the constants will almost certainly get compiled inline where they are referenced.
The only reason to prefer one over the other would be code clarity and variable scoping. If the constants are really local to the PARSER function-- if they aren't likely to be useful to other methods in the package, they ought to be declared as part of the function. If, on the other hand, they are likely to be useful to other methods in the package, they ought to be declared as part of the package body. If they are likely to be useful to methods outside the package, they ought to be declared as part of the package specification.

Resources