Reputation: 748
Create some package:
create or replace package my_package is
some_var number := 10;
end;
and use it in Sql:
select my_package.some_var from dual
So it gives error PLS-221
.
P.S. I know that I can use wrapper function. My question is why this is not allowed. Can anyone point to the documentation where the reason?
Upvotes: 3
Views: 1355
Reputation: 8518
I am going to jump and try to answer your question. It is one I heard of sometimes and indeed has been for a while as a Enhancement Request ( Base ER: ENH 6525013 ), as it was very well pointed by @Anum Kumar.
Why is not possible ? Well, I think the Oracle developers of PL/SQL though about Packages merely as collections of logical subprograms and routines. So make available variables directly to external APIs ( OCI or Java ) was never the intention of the concept.
You don't really have a document link telling you that is not possible, as far as I know, but if you read the documentation of the concept itself, you might get some insights:
A package is a schema object that groups logically related PL/SQL types, variables, constants, subprograms, cursors, and exceptions. A package is compiled and stored in the database, where many applications can share its contents. A package always has a specification, which declares the public items that can be referenced from outside the package. In either the package specification or package body, you can map a package subprogram to an external Java or C subprogram by using a call specification, which maps the external subprogram name, parameter types, and return type to their SQL counterparts.
That is the key, you can map any subprogram of a package to any external Java, C routine; but you can't reference a constant variable directly without the corresponding subprogram ( in your case a function ).
However, you can't use it on SQL, but you can in PL/SQL. Keep in mind that Oracle contains different areas in the Library cache to handle SQL and PLSQL. The library cache holds executable forms of PL/SQL programs and Java classes. These items are collectively referred to as program units.
Example
CREATE OR REPLACE PACKAGE pkg IS
n NUMBER := 5;
END pkg;
/
Package created.
SQL> CREATE OR REPLACE PACKAGE sr_pkg IS
PRAGMA SERIALLY_REUSABLE;
n NUMBER := 5;
END sr_pkg;
/
Package created.
SQL> select sr_pkg.n from dual ;
select sr_pkg.n from dual
*
ERROR at line 1:
ORA-06553: PLS-221: 'N' is not a procedure or is undefined
SQL> set serveroutput on
SQL> BEGIN
pkg.n := 10;
sr_pkg.n := 10;
END;
/
PL/SQL procedure successfully completed.
SQL> BEGIN
DBMS_OUTPUT.PUT_LINE('pkg.n: ' || pkg.n);
DBMS_OUTPUT.PUT_LINE('sr_pkg.n: ' || sr_pkg.n);
END;
/
pkg.n: 10
sr_pkg.n: 5
PL/SQL procedure successfully completed.
In the example above, I can't use the SQL engine to reference a constant variable, as I would need a subprogram or routine ( this is an OCI call, but it might very well be a Java program, ProC, etc. I specifically used one of the packages as serially_reusable
that you can check how the variable does not change even if I try to.
However, if I don't use the SQL engine, I can use it without any problem within PL/SQL.
I hope it clarifies.
Upvotes: 3