删除“确定性”关键字。确定性意味着对于同一组输入,我可以返回相同的输出,而无需再次评估该函数。你有no输入到该函数,所以我们永远不需要运行它。因此我们将返回 null,例如(省略您的设置代码)
--
-- with deterministic
--
SQL> CREATE OR REPLACE PACKAGE Parameters_PKG
2 AUTHID DEFINER
3 AS
4 FUNCTION get_Client_ID RETURN VARCHAR2 deterministic;
5 PROCEDURE Set_Client_ID (p_Client_ID VARCHAR2);
6 END Parameters_PKG
7 ;
8 /
Package created.
SQL> CREATE OR REPLACE PACKAGE BODY Parameters_PKG
2 AS
3 Client_ID VARCHAR2(255);
4 FUNCTION get_Client_ID RETURN VARCHAR2
5 AS
6 PRAGMA UDF;
7 BEGIN
8 IF Client_ID IS NULL THEN
9 RAISE_APPLICATION_ERROR(-20001, 'Fatal error.');
10 END IF;
11 RETURN Client_ID;
12 END get_Client_ID;
13 PROCEDURE Set_Client_ID (P_Client_ID VARCHAR2)
14 IS
15 BEGIN
16 Client_ID := UPPER(TRIM(p_Client_ID));
17 END Set_Client_ID;
18 END Parameters_PKG;
19 /
Package body created.
SQL>
SQL>
SQL> exec Parameters_PKG.Set_Client_ID('TEST')
PL/SQL procedure successfully completed.
SQL> SELECT f.mth, f.just_data
2 FROM facts f, DIM_CALENDAR c
3 WHERE c.CLIENT_ID = Parameters_PKG.Get_Client_ID
4 AND F.mth = C.mth
5 ;
FROM facts f, DIM_CALENDAR c
*
ERROR at line 2:
ORA-00604: error occurred at recursive SQL level 1
ORA-20001: Fatal error.
ORA-06512: at "MCDONAC.PARAMETERS_PKG", line 9
SQL>
SQL> exec Parameters_PKG.Set_Client_ID('wrong_value_to_have_0_rows_returned')
PL/SQL procedure successfully completed.
SQL>
SQL> SELECT f.mth, f.just_data
2 FROM facts f, DIM_CALENDAR c
3 WHERE c.CLIENT_ID = Parameters_PKG.Get_Client_ID
4 AND F.mth = C.mth
5 ;
SELECT f.mth, f.just_data
*
ERROR at line 1:
ORA-00604: error occurred at recursive SQL level 1
ORA-20001: Fatal error.
ORA-06512: at "MCDONAC.PARAMETERS_PKG", line 9
--
-- without deterministic
--
SQL>
SQL> CREATE OR REPLACE PACKAGE Parameters_PKG
2 AUTHID DEFINER
3 AS
4 FUNCTION get_Client_ID RETURN VARCHAR2;
5 PROCEDURE Set_Client_ID (p_Client_ID VARCHAR2);
6 END Parameters_PKG
7 ;
8 /
Package created.
SQL> CREATE OR REPLACE PACKAGE BODY Parameters_PKG
2 AS
3 Client_ID VARCHAR2(255);
4 FUNCTION get_Client_ID RETURN VARCHAR2
5 AS
6 PRAGMA UDF;
7 BEGIN
8 IF Client_ID IS NULL THEN
9 RAISE_APPLICATION_ERROR(-20001, 'Fatal error.');
10 END IF;
11 RETURN Client_ID;
12 END get_Client_ID;
13 PROCEDURE Set_Client_ID (P_Client_ID VARCHAR2)
14 IS
15 BEGIN
16 Client_ID := UPPER(TRIM(p_Client_ID));
17 END Set_Client_ID;
18 END Parameters_PKG;
19 /
Package body created.
SQL>
SQL>
SQL> exec Parameters_PKG.Set_Client_ID('TEST')
PL/SQL procedure successfully completed.
SQL> SELECT f.mth, f.just_data
2 FROM facts f, DIM_CALENDAR c
3 WHERE c.CLIENT_ID = Parameters_PKG.Get_Client_ID
4 AND F.mth = C.mth
5 ;
MTH JUST_DATA
------ ------------------------------------------------------------------------------------------------------------------------
M01 C6537FE410CFA617AFE7F17E6DD72BD9A6EF9ED08CA1216A811320A31A1FE0F9E57D832061B1A7EAA3534D8473098CBF
1 row selected.
SQL>
SQL> exec Parameters_PKG.Set_Client_ID('wrong_value_to_have_0_rows_returned')
PL/SQL procedure successfully completed.
SQL>
SQL> SELECT f.mth, f.just_data
2 FROM facts f, DIM_CALENDAR c
3 WHERE c.CLIENT_ID = Parameters_PKG.Get_Client_ID
4 AND F.mth = C.mth
5 ;
no rows selected
SQL>
SQL>
这是使用 CONTEXT 变量的替代方法
SQL> CREATE TABLE factS
2 ( mth VARCHAR2(6 BYTE) NOT NULL
3 , just_data VARCHAR2(120 BYTE) NOT NULL
4 )
5 PARTITION BY LIST (mth)
6 (
7 PARTITION M01 VALUES ('M01')
8 , PARTITION M02 VALUES ('M02')
9 , PARTITION M03 VALUES ('M03')
10 , PARTITION M04 VALUES ('M04')
11 , PARTITION M05 VALUES ('M05')
12 , PARTITION MAX_VALUE VALUES (DEFAULT)
13 LOGGING
14 ROW STORE COMPRESS BASIC
15 )
16 ;
Table created.
SQL> INSERT INTO facts SELECT 'M' || TO_CHAR(LEVEL, 'FM09'), STANDARD_HASH(LEVEL, 'SHA384' ) FROM dual connect BY LEVEL < 4;
3 rows created.
SQL> COMMIT;
Commit complete.
SQL>
SQL> CREATE TABLE DIM_CALENDAR
2 (
3 CLIENT_ID VARCHAR2(10 BYTE) NOT NULL,
4 mth VARCHAR2(6 BYTE) NOT NULL
5 )
6 ;
Table created.
SQL> INSERT INTO DIM_CALENDAR SELECT 'TEST', 'M' || TO_CHAR(LEVEL, 'FM09') FROM dual connect BY LEVEL < 2;
1 row created.
SQL> INSERT INTO DIM_CALENDAR SELECT 'OTHER', 'M' || TO_CHAR(LEVEL, 'FM009') FROM dual connect BY LEVEL < 10;
9 rows created.
SQL> INSERT INTO DIM_CALENDAR SELECT 'ANOTHER', 'M' || TO_CHAR(LEVEL, 'FM09') FROM dual connect BY LEVEL < 2;
1 row created.
SQL> COMMIT;
Commit complete.
SQL> create context my_context using Parameters_PKG;
Context created.
SQL> CREATE OR REPLACE PACKAGE Parameters_PKG AS
2 PROCEDURE Set_Client_ID (p_Client_ID VARCHAR2);
3 END Parameters_PKG;
4 /
Package created.
SQL> CREATE OR REPLACE PACKAGE BODY Parameters_PKG AS
2
3 PROCEDURE Set_Client_ID (P_Client_ID VARCHAR2)
4 IS
5 BEGIN
6 dbms_session.set_context('MY_CONTEXT','CLIENT_ID',UPPER(TRIM(p_Client_ID)));
7 END Set_Client_ID;
8 END Parameters_PKG;
9 /
Package body created.
SQL> exec Parameters_PKG.Set_Client_ID('TEST')
PL/SQL procedure successfully completed.
SQL> SELECT f.mth, f.just_data
2 FROM facts f, DIM_CALENDAR c
3 WHERE c.CLIENT_ID = sys_context('MY_CONTEXT','CLIENT_ID')
4 AND F.mth = C.mth
5 ;
MTH
------
JUST_DATA
----------------------------------------------------------------------------------------------------
M01
C6537FE410CFA617AFE7F17E6DD72BD9A6EF9ED08CA1216A811320A31A1FE0F9E57D832061B1A7EAA3534D8473098CBF
1 row selected.
SQL>
SQL> exec Parameters_PKG.Set_Client_ID('wrong_value_to_have_0_rows_returned')
PL/SQL procedure successfully completed.
SQL>
SQL> SELECT f.mth, f.just_data
2 FROM facts f, DIM_CALENDAR c
3 WHERE c.CLIENT_ID = sys_context('MY_CONTEXT','CLIENT_ID')
4 AND F.mth = C.mth
5 ;
no rows selected
SQL>