1.15 Calling PL/SQL Functions in SQL

Stored functions can be called from SQL statements in a manner similar to built-in functions like DECODE, NVL, or RTRIM. This is a powerful technique for incorporating business rules into SQL in a simple and elegant way. Unfortunately, there are a number of caveats and restrictions.

The most notable caveat is that stored functions executed from SQL are not by default guaranteed to follow the statement-level read consistency model of the database. Unless the SQL statement and any stored functions in that statement are in the same read-consistent transaction (even if they are read-only), each execution of the stored function may look at a different time-consistent set of data. To avoid this potential problem, you need to ensure read consistency programmatically by issuing the SET TRANSACTION READ ONLY or SET TRANSACTION ISOLATION LEVEL SERIALIZABLE statement before executing your SQL statement containing the stored function. A COMMIT or ROLLBACK then needs to follow the SQL statement to end this read-consistent transaction.

1.15.1 Calling a Function

The syntax for calling a stored function from SQL is the same as that used to reference it from PL/SQL:

[schema_name.][pkg_name.]func_name[@db_link]
   [parm_list]

schema_name is optional and refers to the user/owner of the function or package. pkg_name is optional and refers to the package containing the called function. func_name is required and is the function name. db_link is optional and refers to the database link name to the remote database containing the function. parm_list is optional, as are the parameters passed to the function.

The following are example calls to the GetTimestamp function in the time_pkg example seen earlier in Section 1.14.1:

-- Capture system events.
INSERT INTO v_sys_event (timestamp ,event ,qty_waits)
   SELECT time_pkg.GetTimestamp ,event ,total_waits
   FROM v$system_event

-- Capture system statistics.
INSERT INTO v_sys_stat (timestamp,stat#,value)
   SELECT time_pkg.GetTimestamp ,statistic# ,value
   FROM v$sysstat;

1.15.2 Requirements and Restrictions

There are a number of requirements for calling stored functions in SQL:

  • All parameters must be IN; no IN OUT or OUT parameters are allowed.

  • The datatypes of the function's parameters and RETURN must be compatible with RDBMS datatypes. You cannot have arguments or RETURN types like BOOLEAN, programmer-defined record, associative array, etc.

  • The parameters passed to the function must use positional notation; named notation is not supported.

  • The function must be stored in the database, not in a local program, Developer/2000 PL/SQL library, or form.

1.15.3 Calling Packaged Functions in SQL

Prior to Oracle8i, it was necessary to assert the purity level of a packaged procedure or function when using it directly or indirectly in a SQL statement. Beginning with Oracle8i, the PL/SQL runtime engine determines a program's purity level automatically if no assertion exists. The RESTRICT_REFERENCES pragma is still supported for backward compatibility, but has been deprecated in Oracle9i.

The RESTRICT_REFERENCES pragma asserts a purity level. The syntax for the RESTRICT_REFERENCES pragma is:

PRAGMA RESTRICT_REFERENCES (program_name | DEFAULT,
   purity_level);

The keyword DEFAULT applies to all methods of an object type or all programs in a package.

There can be from one to five purity levels, in any order, in a comma-delimited list. The purity level describes to what extent the program or method is free of side effects. Side effects are listed in the following table with the purity levels they address:

Purity level

Description

Restriction

WNDS

Write No Database State

Executes no INSERT, UPDATE, or DELETE statements.

RNDS

Read No Database State

Executes no SELECT statements.

WNPS

Write No Package State

Does not modify any package variables.

RNPS

Read No Package State

Does not read any package variables.

TRUST

?

Does not enforce the restrictions declared but allows the compiler to trust they are true.

1.15.4 Column/Function Name Precedence

If your function has the same name as a table column in your SELECT statement and the function has no parameter, then the column takes precedence over the function. To force the RDBMS to resolve the name to your function, prepend the schema name to it:

CREATE TABLE emp(new_sal NUMBER ...);
CREATE FUNCTION new_sal RETURN NUMBER IS ...;

SELECT new_sal FROM emp;        -- Resolves to column.
SELECT scott.new_sal FROM emp;  -- Resolves to function.