push procedure pop function with sequence number in oracle - oracle

I want to write code for push with procedure and pop with Function .
create or replace package pushpop_demo as
procedure push(val varchar2);
function pop return varchar2;
end pushpop_demo;
create or replace package body pushpop_demo as
subtype my_string_subtype is varchar2(100);
type varchar2_ntt is table of my_string_subtype;
stuff varchar2_ntt := varchar2_ntt();
procedure push(val varchar2)
is
begin
stuff.extend;
stuff(stuff.last) := val;
end push;
function pop return varchar2
is
subtype my_string_subtype varchar2(100);
begin
if stuff is not empty then
val := stuff(stuff.last);
stuff.delete(stuff.last);
end if;
return val;
end pop ;
but I get error , my question is how can I do this problem with sequence number ??? or other solution .my code does not run anyway . also I do not want use the package .just with procedure and Function .please help me

You need / statement terminators to terminate each PL/SQL block.
You are missing an END; statement at the end of the package body.
You have not declared the VAL variable in the function.
You do not want to re-declare the my_string_subtype type (as it will shadow sub-type declared in the package body).
You can initialise the collection in the declaration section or an alternative is to initialise it in the BEGIN ... END section of the package body.
create or replace package pushpop_demo as
procedure push(val varchar2);
function pop return varchar2;
end pushpop_demo;
/
create or replace package body pushpop_demo as
subtype my_string_subtype is varchar2(100);
type varchar2_ntt is table of my_string_subtype;
stuff varchar2_ntt; -- := varchar2_ntt();
procedure push(val varchar2)
is
begin
stuff.extend;
stuff(stuff.last) := val;
end push;
function pop return varchar2
is
val my_string_subtype;
begin
if stuff is not empty then
val := stuff(stuff.last);
stuff.delete(stuff.last);
end if;
return val;
end pop;
BEGIN
stuff := varchar2_ntt();
END;
/
Then you can use:
BEGIN
pushpop_demo.push('World');
pushpop_demo.push('Hello');
END;
/
and then:
BEGIN
DBMS_OUTPUT.PUT_LINE(pushpop_demo.pop());
DBMS_OUTPUT.PUT_LINE(pushpop_demo.pop());
END;
/
Outputs:
Hello
World
fiddle

Related

PL/SQL "all_search" procedure is not a procedure or is undefined

This function is inside a package, but when I call the function the following error appears: PL/SQL "all_search" is not a procedure or is undefined. Someone can help me?
CREATE OR REPLACE PACKAGE employee_tab IS
FUNCTION all_search (ID_EMP in NUMBER) RETURN O_T_EMPL PIPELINED;
END employee_tab;
/
CREATE OR REPLACE TYPE O_T_EMPL AS TABLE OF O_EMPLOYEE;
/
CREATE OR REPLACE PACKAGE BODY employee_tab IS
FUNCTION all_search (ID_EMP in NUMBER) RETURN O_T_EMPL PIPELINED
IS
TAB_OBJC_EMP O_T_EMPL;
MY_QUERY_SEARCH VARCHAR2(400);
REF_C SYS_REFCURSOR;
MAX_ROW NUMBER := 25;
BEGIN
MY_QUERY_SEARCH := 'SELECT *
FROM EMPLOYEES
WHERE EMPLOYEE_ID = ID_EMP';
open REF_C for MY_QUERY_SEARCH using ID_EMP;
loop
--
fetch REF_C bulk collect into TAB_OBJC_EMP limit MAX_ROW;
exit when TAB_OBJC_EMP.count = 0;
for i in 1..TAB_OBJC_SEE.count
--
loop
pipe row(O_EMPLOYEE(TAB_OBJC_EMP(i).V_O_EMP_ID,
TAB_OBJC_EMP(i).V_O_HIRE_ID,
TAB_OBJC_EMP(i).V_O_DEP_ID)
);
end loop;
--
END loop;
--
CLOSE REF_C;
RETURN;
--
END all_search;
END employee_tab;
/
call function: employee_tab.all_search(1);
You need to assign the result of the function to something, try something like:
DECLARE
l_emp_id NUMBER;
BEGIN
SELECT EMP_ID
INTO l_emp_id
FROM TABLE(employee_tab.all_search(1))
WHERE rownum = 1;
DBMS_OUTPUT.put_line(TO_CHAR(EMP_ID));
END;
/

Procedure checking set up parameters (PL/SQL, ORACLE)

In the package I have couple of procedure that set global variables, example below:
...
PROCEDURE setA (pp IN VARCHAR2)
IS BEGIN global_vName := pp; END;
PROCEDURE setB (qq IN VARCHAR2)
IS BEGIN global_vColor := qq; END;
FUNCTION getA RETURN VARCHAR2
IS BEGIN RETURN global_vName; END;
FUNCTION getB RETURN VARCHAR2
IS BEGIN RETURN global_vColor; END;
...
Now in the PL/SQL block I'm doing test if they are working correclty:
Begin
mypack.setA('NameA');
mypack.setB('ColorB');
End;
How to write a procedure that will check if global_vName and global_vColor are set up?
If they are null procedure should return exception. Please help.
Do you mean this?
FUNCTION getA RETURN VARCHAR2 IS
BEGIN
IF global_vName IS NULL THEN
RAISE NO_DATA_FOUND;
END IF;
RETURN global_vName;
END;
There is no possibility to execute some code after the end statement - you should write it explicitly if you need additional check. As I understand, you want be sure that global variables are always initialized, so you can use the package initialization:
create or replace package body mypack as
PROCEDURE setA (pp IN VARCHAR2)
IS BEGIN global_vName := pp; END;
PROCEDURE setB (qq IN VARCHAR2)
IS BEGIN global_vColor := qq; END;
FUNCTION getA RETURN VARCHAR2
IS BEGIN RETURN global_vName; END;
FUNCTION getB RETURN VARCHAR2
IS BEGIN RETURN global_vColor; END;
< here are your other functions and procedures >
begin
-- here is an initialization section
setA('NameA');
setB('ColorB');
end mypack;
The initialization section will be executed automatically by Oracle before the first user's call to package (function, procedure, cursor, variable, etc.). So you can be sure that your variables are always initialized.

Executing functions in sequence defined in a package

I've been given the task of converting a stored procedure, with several CRUD operations, to a package with functions defined.
When I created the package in Oracle SQL Developer, I defined may functions:
FUNCTION func1 RETURN NUMBER;
FUNCTION func2 RETURN NUMBER;
etc...
I have corresponding code in the 'package body':
FUNCTION func1 RETURN NUMBER
IS
BEGIN
-- some CRUD operation
END;
RETURN 0;
COMMIT;
EXCEPTION
WHEN OTHERS THEN
dbms_output.put_line('FUNCTION func1: error ' || ERR_NUM || ', Msg:' || ERR_MSG);
ROLLBACK;
END func1;
When I run them, I can choose which function to run from the list supplied. My question is what do I need to write or do to have all functions run in sequence with one command?
thanks
If you need to run some procedures in a given order, you need to build a procedure or an anonymous block that calls the procedures in the right order.
For example:
create or replace package aPackage is
procedure runAll;
end;
create or replace package body aPackage is
procedure proc1 is
begin
dbms_output.put_line('Procedure 1');
end proc1;
--
procedure proc2 is
begin
dbms_output.put_line('Procedure 2');
end proc2;
procedure runAll is
begin
proc1;
--
proc2;
--
end runAll;
end;
The call:
SQL> exec aPackage.runAll;
Procedure 1
Procedure 2
PL/SQL procedure successfully completed.
SQL>
I used procedures just to call them without need to assign the result to a variable, but the idea is the same for functions.
With functions:
create or replace package aPackageFun is
function runAll return number;
end;
create or replace package body aPackageFun is
function fun1 return number is
begin
dbms_output.put_line('Inside function 1');
return 1;
end fun1;
--
function fun2 return number is
begin
dbms_output.put_line('Inside function 2');
return 2;
end fun2;
function runAll return number is
vNum1 number;
vNum2 number;
begin
vNum1 := fun1();
--
vNum2 := fun2();
--
return vNum1 + vNum2;
end runAll;
end;
The call:
SQL> select aPackageFun.runAll() from dual;
APACKAGEFUN.RUNALL()
--------------------
3
Inside function 1
Inside function 2
SQL>
About your code, notice that you have a commit after a return: the commit will never be executed.

Join between a collection and a table

I have a problem with procedures in PL/SQL. I have a public procedure declared in a package and I want to call another procedure(private) inside the first one.
PROCEDURE show_notesforstudent (number_id IN number) as
...
DBMS_OUTPUT.PUT_LINE('The notes for the student with number_id X are: '|| Y);
DBMS_OUTPUT.PUT_LINE('here is the call for the private procedure');
erase_student(number_id);
END;
This code is a general example, my code is bigger and I can't put it all here. Here is only the main idea.
For this call I face this error: "Error(31,5): PLS-00313: 'erase_student' not declared in this scope".
The implementation of erase_student procedure is:
PROCEDURE erase_student(n_id students.number_id%type) AS
student_inexistent EXCEPTION;
PRAGMA EXCEPTION_INIT(student_inexistent, -20002);
counter integer;
BEGIN
SELECT COUNT(nmber_id) INTO counter FROM studens where number_id = n_id;
IF counter = 0 THEN
raise student_inexistent;
END IF;
DELETE FROM students WHERE number_id = n_id;
EXCEPTION
WHEN student_inexistent THEN
raise_application_error (-20002, 'Student with number_id' || n_id || ' doesn't exists in database');
END stergere_student;`
Lets simplify your code and make it syntactically correct:
CREATE OR REPLACE PACKAGE package_name
AS
PROCEDURE show_notesforstudent (number_id IN number);
END;
/
CREATE OR REPLACE PACKAGE BODY package_name
AS
PROCEDURE show_notesforstudent (number_id IN number)
AS
BEGIN
erase_student(number_id);
END;
PROCEDURE erase_student(n_id NUMBER) AS BEGIN NULL; END;
END;
/
However, it still won't compile as we get PLS-00313: 'ERASE_STUDENT' not declared in this scope. It can be fixed by re-organising the package to ensure that the private procedure is declared before it is called; like this:
CREATE OR REPLACE PACKAGE BODY package_name
AS
PROCEDURE erase_student(n_id NUMBER) AS BEGIN NULL; END; -- Header and body
PROCEDURE show_notesforstudent (number_id IN number)
AS
BEGIN
erase_student(number_id);
END;
END;
/
However, if you want to keep the order of the procedures in the package then you could just use a forward declaration to declare the header for the private procedure before it is called and declare the body afterwards; like this:
CREATE OR REPLACE PACKAGE BODY package_name
AS
PROCEDURE erase_student(n_id NUMBER); -- Header only
PROCEDURE show_notesforstudent (number_id IN number)
AS
BEGIN
erase_student(number_id);
END;
PROCEDURE erase_student(n_id NUMBER) AS BEGIN NULL; END; -- Header and body
END;
/

how to manually cache the values of function calls in 10g

I have the following code
CREATE OR REPLACE FUNCTION slow_function (p_in IN NUMBER)
RETURN NUMBER
AS
BEGIN
DBMS_LOCK.sleep(1);
RETURN p_in;
END;
/
CREATE OR REPLACE PACKAGE cached_lookup_api AS
FUNCTION get_cached_value (p_id IN NUMBER)
RETURN NUMBER;
PROCEDURE clear_cache;
END cached_lookup_api;
/
CREATE OR REPLACE PACKAGE BODY cached_lookup_api AS
TYPE t_tab IS TABLE OF NUMBER
INDEX BY BINARY_INTEGER;
g_tab t_tab;
g_last_use DATE := SYSDATE;
g_max_cache_age NUMBER := 10/(24*60); -- 10 minutes
-- -----------------------------------------------------------------
FUNCTION get_cached_value (p_id IN NUMBER)
RETURN NUMBER AS
l_value NUMBER;
BEGIN
IF (SYSDATE - g_last_use) > g_max_cache_age THEN
-- Older than 10 minutes. Delete cache.
g_last_use := SYSDATE;
clear_cache;
END IF;
BEGIN
l_value := g_tab(p_id);
EXCEPTION
WHEN NO_DATA_FOUND THEN
-- Call function and cache data.
l_value := slow_function(p_id);
g_tab(p_id) := l_value;
END;
RETURN l_value;
END get_cached_value;
-- -----------------------------------------------------------------
-- -----------------------------------------------------------------
PROCEDURE clear_cache AS
BEGIN
g_tab.delete;
END;
-- -----------------------------------------------------------------
END cached_lookup_api;
/
I want to pass two parameters "pi_value1" and "pi_value2" both of varchar2 to the function slow_function instead of "p_in". Is is possible to cache the results with two in parameters in oracle 10g .
the above code works fine with 1 parameter.
Please any one explain?
You'd need to create a two-dimensional array type to cache the values. Something along the lines of this (omitting the cache expiration code since that isn't changing)
CREATE OR REPLACE PACKAGE BODY cached_lookup_api
AS
TYPE t_pi_value2_tbl IS TABLE OF NUMBER
INDEX BY VARCHAR2(100);
TYPE t_cache IS TABLE OF t_pi_value2_tbl
INDEX BY VARCHAR2(100);
g_cache t_cache;
FUNCTION get_cached_value( p_pi_value1 IN VARCHAR2,
p_pi_value2 IN VARCHAR2 )
IS
BEGIN
RETURN g_cache(p_pi_value1)(p_pi_value2);
EXCEPTION
WHEN no_data_found
THEN
g_cache(p_pi_value1)(p_pi_value2) := slow_function( p_pi_value1, p_pi_value2 );
RETURN g_cache(p_pi_value1)(p_pi_value2);
END;
END;

Resources