For example, they can be called from the following:
Note: Unlike functions, which are called as part of an expression, procedures are called as statements. Therefore, PL/SQL procedures are not directly callable from SQL statements. However, functions called from a PL/SQL statement or referenced in a SQL expression can call a PL/SQL procedure.
[[schema.]package.]function_name[@dblink][(param_1...param_n)]
For example, to reference a function that you have created that is called MY_FUNC, in the MY_FUNCS_PKG package, in the SCOTT schema, and that takes two numeric parameters, you could call it as
SELECT scott.my_funcs_pkg.my_func(10,20) from dual
CREATE TABLE emp(new_sal NUMBER ...); CREATE FUNCTION new_sal RETURN NUMBER IS ...;
Then in the following two statements, the reference to NEW_SAL refers to the column EMP.NEW_SAL:
SELECT new_sal FROM emp; SELECT emp.new_sal FROM emp;
To access the function NEW_SAL, you would enter the following:
SELECT scott.new_sal FROM emp;
Example
For example, to call the TAX_RATE PL/SQL function from schema SCOTT, execute it against the SS_NO and SAL columns in TAX_TABLE, and place the results in the variable INCOME_TAX, specify the following:
SELECT scott.tax_rate (ss_no, sal) INTO income_tax FROM tax_table WHERE ss_no = tax_id;
Listed below are sample calls to PL/SQL functions that are allowed in SQL expressions.
circle_area(radius) payroll.tax_rate(empno) scott.payroll.tax_rate(dependents, empno)@ny
The argument's datatypes and the function's return type are limited to those types that are supported by SQL. For example, you cannot call a PL/SQL function that returns a PL/SQL BINARY_INTEGER from a SQL statement.
CREATE FUNCTION gross_pay
(emp_id IN NUMBER,
st_hrs IN NUMBER DEFAULT 40,
ot_hrs IN NUMBER DEFAULT 0) RETURN NUMBER AS
...
When calling gross_pay from a procedural statement, you can always accept the default value of st_hrs. That is because you can use named notation, which lets you skip parameters, as in
IF gross_pay(eenum,ot_hrs => otime) > pay_limit THEN ...
However, when calling gross_pay from a SQL expression, you cannot accept the default value of st_hrs unless you accept the default value of ot_hrs. That is because you cannot use named notation.
CREATE FUNCTION gross_pay (emp_id IN NUMBER, st_hrs IN NUMBER DEFAULT 40, ot_hrs IN NUMBER DEFAULT 0) RETURN NUMBER AS st_rate NUMBER; ot_rate NUMBER; BEGIN SELECT srate, orate INTO st_rate, ot_rate FROM payroll WHERE acctno = emp_id; RETURN st_hrs * st_rate + ot_hrs * ot_rate; END gross_pay;
Side effects can prevent the parallelization of a query, yield order-dependent (and therefore indeterminate) results, or require that package state be maintained across user sessions (which is not allowed). Therefore, the following rules apply to stored functions called from SQL expressions:
The pragma tells the PL/SQL compiler to deny the packaged function read/write access to database tables, packaged variables, or both. If you try to compile a function body that violates the pragma, you get a compilation error.
To code the pragma RESTRICT_REFERENCES, you use the syntax
PRAGMA RESTRICT_REFERENCES (
function_name, WNDS [, WNPS] [, RNDS] [, RNPS]);
where:
In the example below, the function compound neither reads nor writes database or package state, so you can assert the maximum purity level. Always assert the highest purity level a function allows. That way, the PL/SQL compiler will never reject the function unnecessarily.
CREATE PACKAGE finance AS -- package specification ... FUNCTION compound (years IN NUMBER, amount IN NUMBER, rate IN NUMBER) RETURN NUMBER; PRAGMA RESTRICT_REFERENCES (compound, WNDS, WNPS, RNDS, RNPS); END finance; CREATE PACKAGE BODY finance AS --package body ... FUNCTION compound (years IN NUMBER, amount IN NUMBER, rate IN NUMBER) RETURN NUMBER IS BEGIN RETURN amount * POWER((rate / 100) + 1, years); END compound; -- no pragma in package body END finance;
Later, you might call compound from a PL/SQL block, as follows:
BEGIN ... SELECT finance.compound(yrs,amt,rte) -- function call INTO interest FROM accounts WHERE acctno = acct_id;
CREATE PACKAGE loans AS
prime_rate REAL; -- public packaged variable
...
END loans;
CREATE PACKAGE BODY loans AS
...
BEGIN -- initialization part
SELECT prime INTO prime_rate FROM rates;
END loans;
The initialization code is run only once--the first time the package is referenced. If the code reads or writes database state or package state other than its own, it can cause side effects. Moreover, a stored function that references the package (and thereby runs the initialization code) can cause side effects indirectly. So, to call the function from SQL expressions, you must use the pragma RESTRICT_REFERENCES to assert or imply the purity level of the initialization code.
To assert the purity level of the initialization code, you use a variant of the pragma RESTRICT_REFERENCES, in which the function name is replaced by a package name. You code the pragma in the package specification, where it is visible to other users. That way, anyone referencing the package can see the restrictions and conform to them.
To code the variant pragma RESTRICT_REFERENCES, you use the syntax
PRAGMA RESTRICT_REFERENCES (
package_name, WNDS [, WNPS] [, RNDS] [, RNPS]);
where the arguments WNDS, WNPS, RNDS, and RNPS have the usual meaning.
In the example below, the initialization code reads database state and writes package state. However, you can assert WNPS because the code is writing the state of its own package, which is permitted. So, you assert WNDS, WNPS, RNPS--the highest purity level the function allows. (If the public variable prime_rate were in another package, you could not assert WNPS.)
CREATE PACKAGE loans AS
PRAGMA RESTRICT_REFERENCES (loans, WNDS, WNPS, RNPS);
prime_rate REAL;
...
END loans;
CREATE PACKAGE BODY loans AS
...
BEGIN
SELECT prime INTO prime_rate FROM rates;
END loans;
You can place the pragma anywhere in the package specification, but placing it at the top (where it stands out) is a good idea.
To imply the purity level of the initialization code, your package must have a RESTRICT_REFERENCES pragma for one of the functions it declares. From the pragma, Oracle can infer the purity level of the initialization code (because the code cannot break any rule enforced by a pragma). In the next example, the pragma for the function discount implies that the purity level of the initialization code is at least WNDS:
CREATE PACKAGE loans AS
...
FUNCTION discount (...) RETURN NUMBER;
PRAGMA RESTRICT_REFERENCES (discount, WNDS);
END loans;
...
To draw an inference, Oracle can combine the assertions of all RESTRICT_REFERENCES pragmas. For example, the following pragmas (combined) imply that the purity level of the initialization code is at least WNDS, RNDS:
CREATE PACKAGE loans AS
...
FUNCTION discount (...) RETURN NUMBER;
FUNCTION credit_ok (...) RETURN CHAR;
PRAGMA RESTRICT_REFERENCES (discount, WNDS);
PRAGMA RESTRICT_REFERENCES (credit_ok, RNDS);
END loans;
...
This happens when a packaged function is purer than the package initialization code. Remember, the first time a package is referenced, its initialization code is run. If that reference is a function call, any additional side effects caused by the initialization code occur during the call. So, in effect, the initialization code lowers the purity level of the function.
To avoid this problem, move the package initialization code into a subprogram. That way, your application can run the code explicitly (rather than implicitly during package instantiation) without affecting your packaged functions.
A similar problem arises when a packaged function is purer than a subprogram it calls. This lowers the purity level of the function. Therefore, the RESTRICT_REFERENCES pragma for the function must specify the lower purity level. Otherwise, the PL/SQL compiler will reject the function. In the following example, the compiler rejects the function because its pragma asserts RNDS but the function calls a procedure that reads database state:
CREATE PACKAGE finance AS ... FUNCTION compound (years IN NUMBER, amount IN NUMBER) RETURN NUMBER; PRAGMA RESTRICT_REFERENCES (compound, WNDS, WNPS, RNDS, RNPS); END finance; CREATE PACKAGE BODY finance AS ... FUNCTION compound (years IN NUMBER, amount IN NUMBER) RETURN NUMBER IS rate NUMBER; PROCEDURE calc_loan_rate (loan_rate OUT NUMBER) IS prime_rate REAL; BEGIN SELECT p_rate INTO prime_rate FROM rates; ... END; BEGIN calc_loan_rate(rate); RETURN amount * POWER((rate / 100) + 1, years); END compound; END finance;
However, a RESTRICT_REFERENCES pragma can apply to only one function declaration. So, a pragma that references the name of overloaded functions always applies to the nearest foregoing function declaration. In the following example, the pragma applies to the second declaration of valid:
CREATE PACKAGE tests AS
FUNCTION valid (x NUMBER) RETURN CHAR;
FUNCTION valid (x DATE) RETURN CHAR;
PRAGMA RESTRICT_REFERENCES (valid, WNDS);
...