如何在Oracle的簡單SELECT查詢語句中使用包變量?如何在SQL SELECT語句中使用包常量?
像
SELECT * FROM MyTable WHERE TypeId = MyPackage.MY_TYPE
事情是有可能在全部或僅使用PL/SQL(使用SELECT內BEGIN/END)時?
如何在Oracle的簡單SELECT查詢語句中使用包變量?如何在SQL SELECT語句中使用包常量?
像
SELECT * FROM MyTable WHERE TypeId = MyPackage.MY_TYPE
事情是有可能在全部或僅使用PL/SQL(使用SELECT內BEGIN/END)時?
您不能。
對於公共包變量在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。
不,你不允許這樣做。您需要提供返回該值的函數,然後在SQL中使用該值:
SELECT * FROM MyTable WHERE TypeId = MyPackage.FUN_MY_TYPE
注:我只在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;
UNDEFINED_STRING
--------------------------------------------------------------------------------
?
SQL>選擇從雙undefined_double;
UNDEFINED_DOUBLE
----------------
1.798E+308
SQL> select to_char(undefined_double,'9.999999999999999EEEE')from dual;
TO_CHAR(UNDEFINED_DOUBL
-----------------------
1.797693134862316E+308
SQL>選擇TO_CHAR(undefined_double, '9.99999999999999999EEEE')從雙;
TO_CHAR(UNDEFINED_DOUBLE,
-------------------------
1.79769313486231550E+308
有一種更通用的方式,對我來說很好。您可以使用輸入常量名稱(即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。
感謝'deterministic'子句,這是一個很好的解決方案。 – nop77svk 2014-10-10 07:52:30
不錯的想法,唯一的缺點是錯誤(例如,由於錯別字)將在運行時纔會出現 - 即使您引用了不存在的常量,您的查詢也會毫無錯誤地進行編譯。 – 2014-10-10 08:02:16
您應該標記巡視函數'deterministic',否則Oracle會在每次需要時不必要地調用它'max_number' – Crack 2015-07-02 08:16:04