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

发布于 2024-10-20 05:41:50 字数 191 浏览 2 评论 0原文

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

像这样的事情

SELECT * FROM MyTable WHERE TypeId = MyPackage.MY_TYPE

是否可能完全或仅在使用 PL/SQL 时(在 BEGIN/END 中使用 SELECT)?

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

Is it possible at all or only when using PL/SQL (use SELECT within BEGIN/END)?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

杯别 2024-10-27 05:41:50

你不能。

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

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.
旧梦荧光笔 2024-10-27 05:41:50

有一种更通用的方法对我来说效果很好。您使用输入常量名称(即 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 个函数,并且可以利用现有的 packages.constants 的优势。

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.

清醇 2024-10-27 05:41:50

注意:我只在 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>从 Dual 中选择 undefined_int;

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

SQL>从对偶中选择未定义的字符串;

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

SQL>从对偶中选择 undefined_double;

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

SQL>从 Dual 中选择 to_char(undefined_double,'9.999999999999999EEEE') ;

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

SQL>从 Dual 中选择 to_char(undefined_double,'9.99999999999999999EEEE') ;

TO_CHAR(UNDEFINED_DOUBLE,
-------------------------
 1.79769313486231550E+308

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
宫墨修音 2024-10-27 05:41:50

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

SELECT * FROM MyTable WHERE TypeId = MyPackage.FUN_MY_TYPE

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
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文