oracle-如何在SQL SELECT语句中使用包常量?

如何在Oracle中的简单SELECT查询语句中使用包变量?

就像是

SELECT * FROM MyTable WHERE TypeId = MyPackage.MY_TYPE

使用PL / SQL(在BEGIN / END中使用SELECT)完全有可能吗?

blerontin asked 2020-08-10T23:11:05Z
4个解决方案
59 votes

你不能

对于要在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.

问候,
抢。

Rob van Wijk answered 2020-08-10T23:11:32Z
13 votes

有一种更通用的方法对我来说很好。 使用输入常量名称(即schema.package.constantname)创建一个函数,该函数将为您返回常量值。 您可以通过绑定res变量来执行立即执行的PL / SQL块(请参见示例)。

函数看起来像这样:

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。

Björn answered 2020-08-10T23:12:05Z
7 votes

注意:我仅在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
Nathaniel Mills answered 2020-08-10T23:12:56Z
4 votes

不,您不能这样做。 您需要提供一个返回值的函数,然后在SQL中使用该函数:

SELECT * FROM MyTable WHERE TypeId = MyPackage.FUN_MY_TYPE
Tony Andrews answered 2020-08-10T23:13:16Z
translate from https://stackoverflow.com:/questions/5178830/how-to-use-a-package-constant-in-sql-select-statement