PLS-00231: Function may not be used in SQL - oracle

I want to test my pipelined function without creating a package. The following example is simplified:
DECLARE
FUNCTION testDC RETURN NCOL PIPELINED IS
BEGIN
PIPE ROW(5);
END;
BEGIN
FOR cur IN (select * from table (testDC())) LOOP
dbms_output.put_line('--> ');
END LOOP;
END;
But I get this error:
ORA-06550: line 7, column 7: pls-00231: function TESTDC may not be used in SQL
ORA-06550: line 7, column 7: PL/SQL: ORA-00904: : invalid identifier
ORA-06550: line 7, column 7: PL/SQL: SQL Statement ignored
What is better way to test these function?

Create your pipelined function as a standalone procedure or package member. Then you can call it from your script.
Also ensure that the NCOL parameter you refer to is declared in a schema that can be accessed by the calling script.

You can't access a table function direct in PL/SQL - see the test case below. So as other pointed out you must define the table function as standalone or packaged.
DECLARE
res NUMBER;
FUNCTION testDC RETURN NCOL PIPELINED IS
BEGIN
PIPE ROW(5);
END;
BEGIN
res := testDC();
dbms_output.put_line('--> '||res);
END;
/
ORA-06550: line 3, column 12:
PLS-00653: aggregate/table functions are not allowed in PL/SQL scope

Related

How to execute oracle function in oracle apex online

I have function in oracle apex that returns true or false. When i use sqlcommand function of oracle apex I'm not able to execute the function
function authenticateUser(p_username in varchar2 ,p_password in varchar2 )
return boolean
is
p_user Users.USERNAME%type;
begin
select USERNAME into p_user from Users where upper(USERNAME)=upper(p_username) and upper(PASSWORD) = upper(p_password);
return true;
exception
when NO_DATA_FOUND then
return false;
end authenticateUser;
When i run
begin
PKG_AUTHORIZATION.authenticateUser(:p_username,:p_password);
end;
It display error as
ORA-06550: line 3, column 1:
PLS-00221: 'AUTHENTICATEUSER' is not a procedure or is undefined
ORA-06550: line 3, column 1:
PL/SQL: Statement ignored
ORA-06512: at "SYS.DBMS_SQL", line 1721
1. begin
2. PKG_AUTHORIZATION.authenticateUser(:p_username,:p_password);
3. end;
and When I write
select PKG_AUTHORIZATION.authenticateUser(:p_username,:p_password) from dual;
It throws error as
ORA-00902: invalid datatype
I suppose that function exists within the package, right?
As it returns Boolean, you can't use it directly from SQL, but PL/SQL, such as:
declare
l_val varchar2(20);
begin
l_val := case when PKG_AUTHORIZATION.authenticateUser(:p_username,:p_password) then 'true'
else 'false'
end;
end;
But, you don't have to worry about it. As you tagged the question with the Oracle Apex tag, I presume you use this function for your own authentication (instead of built-in one). If that's so, you just have to name the function which is supposed to do the job and put its name into the "Authentication function name" item.

Apex button and procedure

Im trying to create button in Apex which execute given procedure. As input values I gave two date fields called Poczatek and Koniec. The button should execute this procedure on submit. It perfectly works in Oracle, but throw a lot of errors in Apex.
set serveroutput on
create or replace procedure KORELACJA(:Poczatek, :Koniec)
IS
miasto VARCHAR(25);
korelacja NUMBER;
cursor c1 is
SELECT TEMP.nazwa, corr(TEMP.temperatura, WILGOTNOSC.wilg)
FROM TEMP INNER JOIN WILGOTNOSC
on TEMP.nazwa = WILGOTNOSC.nazwa
and TEMP.data = WILGOTNOSC.data
WHERE TEMP.data between to_date(:Poczatek, 'YYYY-MM-DD') and to_date(:Koniec, 'YYYY-MM-DD')
GROUP BY TEMP.nazwa;
BEGIN
DBMS_OUTPUT.put_line(RPAD('Miasto',10)||RPAD('Korelacja',10));
open c1;
FOR i IN 1..6
LOOP
commit;
fetch c1 into miasto, korelacja;
DBMS_OUTPUT.put_line(RPAD(miasto,10)||RPAD(korelacja,10));
END LOOP;
close c1;
END KORELACJA;
/
Errors look like this:
1 error has occurred
ORA-06550: line 2, column 5: PL/SQL: ORA-00922: missing or invalid option
ORA-06550: line 2, column 1: PL/SQL: SQL Statement ignored ORA-06550: line 6,
column 11: PLS-00103: Encountered the symbol "NUMBER" when expecting one of the
following: := . ( # % ; ORA-06550: line 9, column 18: PLS-00103: Encountered the symbol "JOIN" when
expecting one of the following: , ; for group having intersect minus order start
union where connect
Anyone knows the solution?
I'd suggest you to leave the procedure in the database; call it from Apex.
As you said that it works OK, I'm not going to examine the code. Just modify the first line:
create or replace procedure KORELACJA(par_Poczatek in date,
par_Koniec in date)
is ...
Then, in Apex process, call the procedure as
korelacja(:p1_poczatek, :p2_koniec);
Note that you might need to apply TO_DATE function to those items, using appropriate format mask, such as
korelacja(to_date(:p1_poczatek, 'dd.mm.yyyy',
to_date(:p1_koniec , 'dd.mm.yyyy');
If you insist on keeping the procedure in Apex' process (I wouldn't recommend it), the you don't need CREATE PROCEDURE but an anonymous PL/SQL block. It won't accept any parameters - use Apex items directly.
declare
miasto VARCHAR(25);
korelacja NUMBER;
cursor ...
WHERE TEMP.data between to_date(:p1_Poczatek, 'YYYY-MM-DD') ...
begin
...
end;

PLS-00306: wrong number or types of arguments in call to a Oracle SP

I'm trying to execute a below SP and it throws be the below error:
CREATE OR REPLACE PROCEDURE denodo.CLEAR_INDEX
( INDEX_NAME1 IN VARCHAR2,
INDEX_NAME2 IN VARCHAR2,
IT_WORKED OUT BOOLEAN ) as
BEGIN
IT_WORKED := FALSE;
EXECUTE IMMEDIATE 'drop index ' || INDEX_NAME1;
EXECUTE IMMEDIATE 'drop index ' || INDEX_NAME2;
IT_WORKED := TRUE;
EXCEPTION
WHEN OTHERS THEN
IT_WORKED := FALSE;
END CLEAR_INDEX;
CLEAR_INDEX#0 [JDBC ROUTE] [ERROR] Received exception with message 'ORA-06550: line 1, column 7:
PLS-00306: wrong number or types of arguments in call to 'CLEAR_INDEX'
ORA-06550: line 1, column 7:
PL/SQL: Statement ignored
What is going on here? appreciate your help.
This error you generally face when you deal with BOOLEAN datatype as OUT parameter and you try to print it or do any operation with any other inbuilt Oracle packages. You cannot directly use BOOLEAN datatype in dbms_output.put_line or any other DBMS package. For instance,if you want to print the OUT parameter you need to use sys.diutil.bool_to_int.
See below example which demonstrate the error you faced when you try to execute as below:
DECLARE
inx VARCHAR2(100):='ABC';
var BOOLEAN;
BEGIN
CLEAR_INDEX(INDEX_NAME1=>inx ,IT_WORKED =>var);
dbms_output.put_line(var);
END;
You face the issue:
ORA-06550: line 6, column 3:
PLS-00306: wrong number or types of arguments in call to 'PUT_LINE'
ORA-06550: line 6, column 3:
PL/SQL: Statement ignored
06550. 00000 - "line %s, column %s:\n%s"
*Cause: Usually a PL/SQL compilation error.
*Action
To overcome such issue you must execute as below:
DECLARE
inx VARCHAR2(100):='ABC';
var BOOLEAN;
var1 varchar2(10);
BEGIN
CLEAR_INDEX(INDEX_NAME1=>inx ,IT_WORKED =>var);
var1:=CASE WHEN (sys.diutil.bool_to_int(var)) = 1 THEN 'TRUE'
WHEN (sys.diutil.bool_to_int(var)) = 0 THEN 'FALSE'
END;
dbms_output.put_line(var1);
END;
Output:
anonymous block completed
Mine is a similar case, however, a different call to a function, which has return type as Boolean and the input to the function is varchar2.
So, this is what I am doing:
Declare
v_ret1 varchar2(1000);
v_ret BOOLEAN;
Begin
v_ret := CASE WHEN SEI_PROCESS_MF_MNL_INVC_PKG.f_process_mf_mnl_invc(v_ret1) = 1 THEN 'TRUE'
WHEN SEI_PROCESS_MF_MNL_INVC_PKG.f_process_mf_mnl_invc(v_ret1) = 0 THEN 'FALSE'
END;
dbms_output.put_line(v_ret);
end;
I just wanted to see output of v_ret so that I can use that for further decision making. If v_ret is of type Boolean, the output should be either "TRUE" or "FALSE".

How to run a procedure having cursor output in oracle?

I have created a procedure in oracle as follows
create or replace procedure jobsfetch
(id varchar2,jobcursor out sys_refcursor)
as
begin
open jobcursor for
select * from shop.jobs where job_id = id;
end;
I run the procedure in SQL*Plus using:
exec jobsfetch('AD_ASST');
But I'm getting the following error
ERROR at line 1:
ORA-06550: line 1, column 7:
PLS-00306: wrong number or types of arguments in call to 'JOBSFETCH'
ORA-06550: line 1, column 7:
PL/SQL: Statement ignored
How to execute this procedure since its having only one input parameter?
try this:
variable CURSOR_LIST REFCURSOR;
exec jobsfetch('AD_ASST',:CURSOR_LIST);
print CURSOR_LIST;
You can simply use a plsql block:
declare
outCur sys_refcursor;
begin
jobsfetch('AD_ASST', outCur);
/* what you need to do with the cursor */
end;
The problem is that your procedure has an out parameter, but you don't supply it.
You can't exec jobsfetch('AD_ASST');
I recommend putting the whole thing in a plsql block like Aleksej.
declare
outCur sys_refcursor;
begin
jobsfetch('AD_ASST', outCur);
/* what you need to do with the cursor */
end;
This will give you the cursor that you opened in outCur and you can do whatever you need to do with it.

Executing Stored Procedure - Oracle PL SQL

I'm currently trying to execute a stored procedure in Oracle PL SQL. I keep running into the same error for the below with execution.
I've tried both execution with the same error
SET SERVEROUTPUT ON;
EXEC get_phone(200.00,500.00);
OR
SET SERVEROUTPUT ON;
DECLARE
c_minprice products.price%type;
c_maxprice products.price%type;
BEGIN
c_minprice := get_phone(200);
c_maxprice := get_phone(500);
END;
ERROR from executing the above:
c_minprice := get_phone(200);
*
ERROR at line 5:
ORA-06550: line 5, column 15:
PLS-00306: wrong number or types of arguments in call to 'GET_PHONE'
ORA-06550: line 5, column 1:
PL/SQL: Statement ignored
ORA-06550: line 6, column 15:
PLS-00306: wrong number or types of arguments in call to 'GET_PHONE'
ORA-06550: line 6, column 1:
PL/SQL: Statement ignored
****Sample Snip-its form my code:
CREATE OR REPLACE PROCEDURE get_phone
(
c_minprice IN products.price%type,
c_maxprice IN products.price%type,
i_result OUT VARCHAR2
) AS
--Checking if starting price range is valid or not
IF c_minprice IS NULL THEN
i_result := 'Starting price range should be valid and cannot be empty';
RAISE V_MINPRICE; -- Raising exception if starting price is null
END IF;
--Checking if end price range is valid or not
IF c_maxprice IS NULL THEN
i_result := 'End price range should be valid and cannot be empty';
RAISE V_MAXPRICE; -- Raising exception if end price is null
END IF;
Your procedure requires three parameters so you have to pass in three parameters
DECLARE
l_result varchar2(100);
BEGIN
get_phone( 200, 500, l_result );
END;
/
should work. Of course, your procedure seems rather pointless. And if the goal is simply to return a result, you really ought to be using a function rather than a procedure with an out parameter.
get_phone expects 3 arguments, c_minprice, c_maxprice and i_result. You are only passing it one number. Pass it the rest of the arguments.

Resources