How to use a package constant in SQL SELECT statement?

后端 未结 4 683
难免孤独
难免孤独 2020-12-04 23:53

How can I use a package variable in a simple SELECT query statement in Oracle?

Something like

SELECT * FROM MyTable WHERE TypeId = MyPackage.MY_TYPE
         


        
相关标签:
4条回答
  • 2020-12-05 00:02

    Note: I only tried this in Oracle 11g.

    I had a similar need and found it easier to simply declare a function (without the package) to return the desired value. To put these in ddl for import, remember to separate each function declaration with the / character. For example:

    CREATE OR REPLACE FUNCTION UNDEFINED_INT RETURN NUMBER AS BEGIN RETURN 2147483646; END;
    /
    CREATE OR REPLACE FUNCTION UNDEFINED_SHORT RETURN NUMBER AS BEGIN RETURN 32766; END;
    /
    CREATE OR REPLACE FUNCTION UNDEFINED_LONG RETURN NUMBER  AS BEGIN RETURN 223372036854775806; END;
    /
    CREATE OR REPLACE FUNCTION UNDEFINED_FLOAT RETURN FLOAT  AS BEGIN RETURN .4028233E38; END;
    /
    CREATE OR REPLACE FUNCTION UNDEFINED_DOUBLE RETURN BINARY_DOUBLE  AS BEGIN RETURN to_binary_double('1.7976931348623155E308'); END;
    /
    CREATE OR REPLACE FUNCTION UNDEFINED_STRING RETURN VARCHAR AS BEGIN RETURN '?'; END;
    /
    

    This allows you to reference the function as though it was a constant value (e.g., you don't even need the parentheses).

    For example (note the to_char methods to show the precision has been preserved): SQL> select undefined_int from dual;

    UNDEFINED_INT
    -------------
       2147483646
    

    SQL> select undefined_string from dual;

    UNDEFINED_STRING
    --------------------------------------------------------------------------------
    ?
    

    SQL> select undefined_double from dual;

    UNDEFINED_DOUBLE
    ----------------
          1.798E+308
    

    SQL> select to_char(undefined_double,'9.999999999999999EEEE') from dual;

    TO_CHAR(UNDEFINED_DOUBL
    -----------------------
     1.797693134862316E+308
    

    SQL> select to_char(undefined_double,'9.99999999999999999EEEE') from dual;

    TO_CHAR(UNDEFINED_DOUBLE,
    -------------------------
     1.79769313486231550E+308
    
    0 讨论(0)
  • 2020-12-05 00:07

    There is a more generic way which works fine for me. You create a function with input constant name (i.e. schema.package.constantname) and it returns you the constant value. You make use of executing immediate a PL/SQL block by binding res variable (see example).

    Function looks like this:

    CREATE OR REPLACE FUNCTION GETCONSTANTVALUE (i_constant IN VARCHAR2)  RETURN NUMBER deterministic AS
    
       res number; 
    BEGIN
    
       execute immediate 'begin :res := '||i_constant||'; end;' using out res;     
       RETURN res;
    
    END;
    /
    

    You can then use the constant of any package in any SQL, i.e. like

    select GETCONSTANTVALUE('PKGGLOBALCONSTANTS.constantname') from dual;
    

    Like this you need only 1 function and you take the advantage to use existing packages.constants.

    0 讨论(0)
  • 2020-12-05 00:11

    No, you aren'e allowed to do that. You would need to provide a function that returns the value and then use that in the SQL:

    SELECT * FROM MyTable WHERE TypeId = MyPackage.FUN_MY_TYPE
    
    0 讨论(0)
  • 2020-12-05 00:17

    You can't.

    For a public package variable to be used in a SQL statement, you have to write a wrapper function to expose the value to the outside world:

    SQL> create package my_constants_pkg
      2  as
      3    max_number constant number(2) := 42;
      4  end my_constants_pkg;
      5  /
    
    Package created.
    
    SQL> with t as
      2  ( select 10 x from dual union all
      3    select 50 from dual
      4  )
      5  select x
      6    from t
      7   where x < my_constants_pkg.max_number
      8  /
     where x < my_constants_pkg.max_number
               *
    ERROR at line 7:
    ORA-06553: PLS-221: 'MAX_NUMBER' is not a procedure or is undefined
    

    Create a wrapper function:

    SQL> create or replace package my_constants_pkg
      2  as
      3    function max_number return number;
      4  end my_constants_pkg;
      5  /
    
    Package created.
    
    SQL> create package body my_constants_pkg
      2  as
      3    cn_max_number constant number(2) := 42
      4    ;
      5    function max_number return number
      6    is
      7    begin
      8      return cn_max_number;
      9    end max_number
     10    ;
     11  end my_constants_pkg;
     12  /
    
    Package body created.
    

    And now it works:

    SQL> with t as
      2  ( select 10 x from dual union all
      3    select 50 from dual
      4  )
      5  select x
      6    from t
      7   where x < my_constants_pkg.max_number()
      8  /
    
             X
    ----------
            10
    
    1 row selected.
    
    0 讨论(0)
提交回复
热议问题