Skip to Main Content

Breadcrumb

Question and Answer

Chris Saxon

Thanks for the question, Nag.

Asked: November 05, 2001 - 3:29 pm UTC

Last updated: August 02, 2007 - 10:05 am UTC

Version: 8.1.7

Viewed 10K+ times! This question is

You Asked

Tom

Iam trying to use a function( which is part of a package) from within my sql statement, and Iam getting the error

pls-00231: function name may not be used in SQL

But when I remove it from the package and create it invidudually , it is working fine.

Can you kindly let me know as why pls-00231: function name may not be used in SQL occurs and how we should trouble shoot it.

thank you

and Tom said...

Is the function in the specification. If not, it is not visible to sql. Consider:

ops$tkyte@ORA717DEV.US.ORACLE.COM> create or replace package my_pkg
2 as
3 procedure p;
4
5 end;
6 /

Package created.

ops$tkyte@ORA717DEV.US.ORACLE.COM>
ops$tkyte@ORA717DEV.US.ORACLE.COM> create or replace package body my_pkg
2 as
3
4 function f return number
5 is
6 begin
7 return 1;
8 end;
9
10
11 procedure p
12 is
13 begin
14 for x in ( select f from dual )
15 loop
16 dbms_output.put_line( 'Yes' );
17 end loop;
18 end;
19
20 end;
21 /

Warning: Package Body created with compilation errors.

ops$tkyte@ORA717DEV.US.ORACLE.COM> show errors
Errors for PACKAGE BODY MY_PKG:

LINE/COL ERROR
-------- -----------------------------------------------------------------
14/13 PL/SQL: SQL Statement ignored
14/20 PLS-00231: function 'F' may not be used in SQL
ops$tkyte@ORA717DEV.US.ORACLE.COM>
ops$tkyte@ORA717DEV.US.ORACLE.COM> create or replace package my_pkg
2 as
3 procedure p;
4 function f return number;
5 end;
6 /

Package created.

ops$tkyte@ORA717DEV.US.ORACLE.COM>
ops$tkyte@ORA717DEV.US.ORACLE.COM> alter package my_pkg compile body;

Package body altered.

ops$tkyte@ORA717DEV.US.ORACLE.COM>
ops$tkyte@ORA717DEV.US.ORACLE.COM> exec my_pkg.p
Yes

PL/SQL procedure successfully completed.


Until the function is "exposed" the SQL engine cannot see it.

Rating

  (15 ratings)

Is this answer out of date? If it is, please let us know via a Comment

Comments

Prasad, October 28, 2004 - 8:47 pm UTC


Duke Ganote, February 11, 2005 - 8:33 am UTC


Great tip!

Nitin, October 12, 2005 - 3:38 pm UTC


just what I needed!

Jermy Hoffman, October 19, 2005 - 11:29 am UTC

THNX

NOT USEFUL COMMENTS

A reader, September 26, 2006 - 7:48 am UTC

...
Tom Kyte
September 26, 2006 - 3:52 pm UTC

well, gee.

"sorry"?

but - hey, have a nice day anyway...

Great answer. Just what I needed. (as usual in ask Tom)

A reader, October 27, 2006 - 12:38 pm UTC


A reader, February 13, 2007 - 10:53 am UTC


Good explanation

JequE, April 03, 2007 - 4:48 pm UTC

I had the exact same problem and a quick search in your site help me a lot. Thanks for sharing your knowledge.

Same issue with private function

Rashmi Sinha, July 30, 2007 - 1:21 pm UTC

I have a function which is in other package and second function declared as private function in the same package. I am able to use function from the other package in my SQL statement but if I try to use function from the same package it give me PLS 00231 error.

Private Function has forward declaration in the package body.

Tom Kyte
July 30, 2007 - 5:46 pm UTC

give tiny example of what you mean.

TINY - I dont NOT want all of your code, I want the smallest possible example that demonstrates your issue.

your text is not followable as a specification.

very tricky

Cristian Cudizio, July 31, 2007 - 11:12 am UTC

i've had same problem and until this morning i could not understant it.
I used the statement

INSERT INTO tableX
(x2000averid,
x2000acncid
)
(
SELECT x.i_x2000averid , x.i_x2000avercnc
from table(TOKENIZE(mynestedtable_nt(i).x2000averacnc2 ,mynestedtable_nt(i).x2000averid )) x
where x.i_x2000avercnc is not null
);

In a procedure part of a package. I've used pipelined function "TOKENIZE" not declared in package declaration and i got pls-00231 at compiling time.
If i put declaration of "TOKENIZE" on package declaration it compiles correctly, but on execution gives:
ORA-22905: cannot access rows from a non-nested table item
So i changed the statement adding CAST on TOKENIZE arguments:
INSERT INTO tableX
(x2000averid,
x2000acncid
)
(
SELECT x.i_x2000averid , x.i_x2000avercnc
from table(TOKENIZE(cast(mynestedtable_nt(i).x2000averacnc2 as varchar(100)), cast(mynestedtable_nt(i).x2000averid as number))) x
where x.i_x2000avercnc is not null
);

So i think that when procedure executes, to execute the statement Oracle switch to SQL engine and it is not able to get nested table elements types.
Could you explain better what appens?
Thanks for your help.
Cristian
Tom Kyte
August 02, 2007 - 10:05 am UTC

it has to do with plsql and changes over the versions.

plsql will parse that sql statement at compile time, extract the references to variables and turn them into binds. It then temporarily lost the "datatype" when it replaced the variables with :bv references. By using cast - you supply that information again and it worked.

this is corrected in current releases of the software - the datatype does not temporarily go missing.

using cast is a perfectly workable solution however

ThanX!

Rob, October 29, 2010 - 5:53 am UTC

Very usefull.
Thanx!

Rob

Don't forget the parametrs

Susi, March 23, 2012 - 11:08 am UTC

Bear in mind that the specification has to be precise. I had a function with one parametr, which I omitted in the package declaration and I still got this error.

Thank you Tom

Hass, May 02, 2012 - 11:59 pm UTC

I am ashamed after seeing your solution .How stupid can i be :)

crystal clear example!

cj, September 19, 2012 - 10:39 am UTC

I'm with Haas from UAE, this seems like such a rookie mistake! Thanks for taking the time to write the pl/sql example.

Spot on !

A reader, October 13, 2017 - 9:18 am UTC

Most useful answer, good job AskTOM !

More to Explore

PL/SQL demos

Check out more PL/SQL tutorials on our LiveSQL tool.

PL/SQL docs

PL/SQL reference manual from the Oracle documentation library