Skip to Main Content

Breadcrumb

Question and Answer

Connor McDonald

Thanks for the question, Amit.

Asked: February 16, 2016 - 12:27 pm UTC

Last updated: February 18, 2016 - 11:00 am UTC

Version: 12

Viewed 1000+ times

You Asked

Greetings,
Kindly requesting you to suggest on use of global variables.
Can we use a result from a collection populated by one package into a different package?
I tried below piece of code but failed, please suggest if it is possible or not?

CREATE OR REPLACE PACKAGE p1
AS
CURSOR c1 (p_employee_id employees.employee_id%TYPE)
IS
SELECT *
FROM employees
WHERE employee_id = p_employee_id;

TYPE aat_e IS TABLE OF c1%ROWTYPE INDEX BY PLS_INTEGER;

lv_e aat_e;

PROCEDURE p1 (p_employee_id employees.employee_id%TYPE);
END p1;
/
CREATE OR REPLACE PACKAGE BODY APPS.p1
AS
PROCEDURE p1 (p_employee_id IN employees.employee_id%TYPE)
AS
BEGIN
OPEN c1 (p_employee_id);

FETCH c1
BULK COLLECT INTO lv_e;

CLOSE c1;

FOR i IN 1 .. lv_e.COUNT
LOOP
DBMS_OUTPUT.PUT_LINE (lv_e(i).first_name);
END LOOP;

ct.p1;

END p1;
END p1;
/
CREATE OR REPLACE PACKAGE APPS.p2
AS
PROCEDURE p2 (p_employee_id IN employees.employee_id%TYPE);
END p2;
/

CREATE OR REPLACE PACKAGE BODY p2
AS
PROCEDURE p2 (p_employee_id IN employees.employee_id%TYPE)
IS
lv_details employees%ROWTYPE;
BEGIN
lv_details := p_employee_id;
p1.p1 (lv_details);

SELECT *
INTO lv_detals
FROM employees
WHERE first_name = p1.lv_e (i).first_name;

DBMS_OUTPUT.put_line (lv_details.employee_id);
END p2;
END p2;

and Chris said...

Yes, you can reference a package variable in another package (provided it's in the spec).

There are a number of issues with the code though:

- line 14 of P1 body references "ct.p1". I'm not sure what this is supposed to do, but it's invalid. Remove it.
- line 8 of P2 body passes a rowtype variable to p1.p1. This accepts an employees.employee_id though. You need to change these to match types
- line 12 refers to a non-existent variable i. Either you need to declare this and assign it a value or replace it with a literal.

If you fix these the code works for me:

create table employees as
  select * from hr.employees;

create or replace package p1
as
  cursor c1 ( p_employee_id employees.employee_id%type )
  is
    select * from employees where employee_id = p_employee_id;
  type aat_e
  is table of c1%rowtype index by pls_integer;
  lv_e aat_e;
  procedure p1 (
      p_employee_id employees.employee_id%type ) ;
end p1;
/
create or replace package body p1
as
  procedure p1 (
      p_employee_id in employees.employee_id%type )
  as
  begin
    open c1 ( p_employee_id ) ;
    fetch c1 bulk collect into lv_e;
    close c1;
    for i in 1 .. lv_e.count
    loop
      dbms_output.put_line ( lv_e ( i ) .first_name ) ;
    end loop;
  end p1;
end p1;
/
create or replace package p2
as
  procedure p2 (
      p_employee_id in employees.employee_id%type ) ;
end p2;
/
create or replace package body p2
as
  procedure p2 (
      p_employee_id in employees.employee_id%type )
  is
    lv_details employees%rowtype;
  begin
    p1.p1 ( p_employee_id ) ;
    select *
    into lv_details
    from employees
    where first_name = p1.lv_e ( 1 ) .first_name;
    dbms_output.put_line ( lv_details.employee_id ) ;
  end p2;
end p2;
/

exec p2.p2(101);

Neena
101

Rating

  (1 rating)

Is this answer out of date? If it is, please let us know via a Comment

Comments

Need more suggeston

Amit Saroha, February 18, 2016 - 5:12 am UTC

I really want to say thanks for your neat and clean reply.
I request you to put some more light on the case I asked.

As the cursor is opened in my p1.p1 procedure, it fetches a result set.
Now I am calling p2.p2 in my p1.p1 and p2.p2 is using the result set of p1.p1 package cursor. (I am not calling p1.p1 in p2.p2).
Please suggest if I can refer p1.p1 cursor result set in p1.p1 by using global variables or any other method (i don't want to pass result as parameters in p2.p2.
Connor McDonald
February 18, 2016 - 11:00 am UTC

Do you mean, "can I fetch the results of package cursor p1.c1 in package p2?".

If so, the answer is yes:

create or replace package p1
as
  cursor c1 ( p_employee_id employees.employee_id%type )
  is
    select * from employees where employee_id = p_employee_id;
  procedure p1 (
      p_employee_id employees.employee_id%type ) ;
end p1;
/
create or replace package body p1
as
  procedure p1 (
      p_employee_id in employees.employee_id%type )
  as
  begin
    open c1 ( p_employee_id ) ;
    
  end p1;
end p1;
/
create or replace package p2
as
  procedure p2 (
      p_employee_id in employees.employee_id%type ) ;
end p2;
/
create or replace package body p2
as
  procedure p2 (
      p_employee_id in employees.employee_id%type )
  is
    lv_details employees%rowtype;
  type aat_e
    is table of p1.c1%rowtype index by pls_integer;
    lv_e aat_e;
  begin
    p1.p1 ( p_employee_id ) ;
  
  fetch p1.c1 bulk collect into lv_e;
    close p1.c1;
    for i in 1 .. lv_e.count
    loop
      dbms_output.put_line ( lv_e ( i ) .first_name ) ;
    end loop;
  end p2;
end p2;
/

exec p2.p2(100);
Steven


If not, you'll have to clarify what you're looking for.

More to Explore

PL/SQL demos

Check out more PL/SQL tutorials on our LiveSQL tool.

PL/SQL docs

PL/SQL reference manual from the Oracle documentation library