Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why Plsql package variables and constants cannot be used in Sql?

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?

like image 410
Si7ius Avatar asked Dec 17 '25 19:12

Si7ius


1 Answers

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.

like image 135
Roberto Hernandez Avatar answered Dec 20 '25 11:12

Roberto Hernandez



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!