Link to home
Start Free TrialLog in
Avatar of steve2312
steve2312Flag for United States of America

asked on

How to reference a packaged procedure to a global variable

Have created a partition key inside a  packaged (Package name Common) procedure using the pseudo code below. The partition key is a concatenated value of p_firstday_p_lastday.

PROCEDURE get_region_partition(p_tablename IN VARCHAR2,
                                 p_firstday  IN region.firstday%TYPE,
                                 p_lastday   IN region.lastday%TYPE) IS
  
    v_partition_sql          VARCHAR2(2000);
    v_partition_exists       NUMBER;
    v_partition_key          VARCHAR2(100);
  
  
  BEGIN
  
    v_partition_key := p_firstday || '_' || p_lastday;
  
    SELECT COUNT(*)
      INTO v_partition_exists
      FROM user_tab_partitions
     WHERE table_name = p_tablename
       AND partition_name = v_partition_key;
  
    IF v_partition_exists = 0 THEN
      BEGIN
        v_partition_key := v_partition_key;
      EXCEPTION
        -- exception raised and handled

      END;
    END IF;
  
    v_partition_sql := 'alter table ' || p_tablename || ' add partition ' ||
                       v_partition_key || ' values (' || p_firstday || '_' || '
                       p_lastday ) ';

Open in new window


In a different package ( say Package B) and in the initialization section, I am making a reference to the partition_key value in the package A by the code below.

    gv_partition_key := common.get_region_partition(p_tablename => region,
                                                             p_firstday  => 20170101,
                                                             p_lastday   => 20170331);

Open in new window



This assignment fails with the error PLS:00357 Table, View or reference not allowed here. Not sure why this initialization fails. Is it because it is procedure?  The intent is to  initialize gv_parition_key to the partition_key value obtained from the procedure get_region_partition inside the package "Common".
SOLUTION
Avatar of Sanjeev Labh
Sanjeev Labh
Flag of Switzerland image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of steve2312

ASKER

Thank you for the suggestion!  I went ahead with creating a function and this worked!

 FUNCTION get_region_partition(p_tablename IN VARCHAR2,
                                p_firstday  IN region.firstday%TYPE,
                                p_lastday   IN region.lastday%TYPE)
    RETURN VARCHAR2 IS
    v_partition_key VARCHAR2(100);
  
  BEGIN
    IF p_tablename = 'REGION' THEN
      EXECUTE IMMEDIATE 'SELECT to_char(p_firstday,''YYYYMMDD'')||''_''||to_char(p_lastday,''YYYYMMDD'') FROM DUAL'
        INTO v_partition_key;
    ELSE
      NULL;
    END IF;
    RETURN v_partition_key;
  END get_region_partition;

Open in new window



However when trying to initialize a global variable gv_partition_key to this function inside another package. The call  fails with wrong number of arguments (PLS-00306) in call to 'get_region_partition'.

  Procedure init_vars (p_parm1 in varchar2, p_parm2 in varchar2) is

 BEGIN
  ...
  ...
  ...
    gv_partition_key := common.get_region_partition(p_tablename => 'REGION',  p_firstday  => 20170101,  p_lastday   => 20170331);
END;

Open in new window

ASKER CERTIFIED SOLUTION
Avatar of slightwv (䄆 Netminder)
slightwv (䄆 Netminder)

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Yes, the function is in the common package.  The first and last day parameters is Date.
Avatar of slightwv (䄆 Netminder)
slightwv (䄆 Netminder)

>>The first and last day parameters is Date.

Then you need to pass in a date or change the input parameters to a number or varchar2.

    gv_partition_key := common.get_region_partition(p_tablename => 'REGION',  p_firstday  => to_date('20170101','YYYYMMDD'),  p_lastday   => to_date('20170331','YYYYMMDD'));

Open in new window


or:

FUNCTION get_region_partition(p_tablename IN VARCHAR2,
                                p_firstday  IN number,
                                p_lastday   IN number)

Open in new window


then you can use:
    gv_partition_key := common.get_region_partition(p_tablename => 'REGION',  p_firstday  => 20170101,  p_lastday   => 20170331);

Open in new window


Personally, I would go with the second option since you don't need actual dates inside the function.
Your function would be:
FUNCTION get_region_partition(p_tablename IN VARCHAR2,
                                p_firstday  IN number,
                                p_lastday   IN number)
    RETURN VARCHAR2 IS
BEGIN

	return case when p_tablename = 'REGION' THEN to_char(p_firstday) ||'_'|| to_char(p_lastday) end;
END get_region_partition;

Open in new window

Thank you for the suggestions.  The solutions worked