Как использовать константу пакета в операторе SQL SELECT? - PullRequest
40 голосов
/ 03 марта 2011

Как я могу использовать переменную пакета в простом операторе запроса SELECT в Oracle?

Что-то вроде

SELECT * FROM MyTable WHERE TypeId = MyPackage.MY_TYPE

Возможно ли это вообще или только при использовании PL / SQL (используйте SELECT в BEGIN / END)?

Ответы [ 4 ]

58 голосов
/ 03 марта 2011

Вы не можете.

Чтобы переменная общедоступного пакета использовалась в операторе SQL, вам нужно написать функцию-обертку для представления значения внешнему миру:

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

Создание функции-оболочки:

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.

И теперь это работает:

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.

С уважением,
Роб.

12 голосов
/ 10 октября 2014

Есть более общий способ, который отлично работает для меня. Вы создаете функцию с именем входной константы (т.е. schema.package.constantname), и она возвращает вам значение константы. Вы используете немедленное выполнение блока PL / SQL путем привязки переменной res (см. Пример).

Функция выглядит так:

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;
/

Затем вы можете использовать константу любого пакета в любом SQL, например,

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

Таким образом, вам нужна только 1 функция, и вы пользуетесь преимуществом, чтобы использовать существующие package.constants.

6 голосов
/ 26 сентября 2012

Примечание: я пробовал это только в Oracle 11g.

У меня была похожая потребность, и мне было проще просто объявить функцию (без пакета), чтобы вернуть желаемое значение. Чтобы поместить их в ddl для импорта, не забудьте разделить каждое объявление функции символом /. Например:

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;
/

Это позволяет вам ссылаться на функцию, как если бы она была постоянным значением (например, вам даже не нужны скобки).

Например (обратите внимание, что методы to_char показывают, что точность была сохранена): SQL> выбрать undefined_int из двойного;

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

SQL> выбрать undefined_string из двойного;

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

SQL> выбрать undefined_double из двойного;

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

SQL> выберите to_char (undefined_double, '9.999999999999999EEEE') из двойного;

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

SQL> выберите to_char (undefined_double, '9.99999999999999999EEEE') из двойного;

TO_CHAR(UNDEFINED_DOUBLE,
-------------------------
 1.79769313486231550E+308
4 голосов
/ 03 марта 2011

Нет, вам нельзя это делать. Вам необходимо предоставить функцию, которая возвращает значение, а затем использовать его в SQL:

SELECT * FROM MyTable WHERE TypeId = MyPackage.FUN_MY_TYPE
...