Cryptic error when attempting to create PL/SQL function - oracle

CREATE OR REPLACE FUNCTION SUPPLIER (Tradename IN DRUG.Tradename%TYPE) RETURN VARCHAR2
IS
returnString VARCHAR2(32767);
BEGIN
returnString := lpad('*',32767,'*');
SELECT Formula,Pharname INTO returnString FROM DRUG
WHERE Tradename=Tradename;
RETURN returnString;
END;
/
When i attempt to create this function, it says this :
Warning : Function created with compilation errors.
When I execute "show err", I get this :
LINE/COL ERROR
-------- -----------------------------------------------------------------
7/2 PL/SQL: SQL Statement ignored
7/44 PL/SQL: ORA-00947: not enough values
Any help is very much appreciated!

ORA-00947 "not enough values"
is being raised on line 7:
SELECT Formula,Pharname INTO returnString
You are selecting two columns, but you only provide one variable to put them in.
You can either add a second variable, or use some kind of expression to concatenate the values, e.g.:
SELECT Formula,Pharname INTO returnFormula,returnPharname
or
SELECT Formula || Pharname INTO returnString

Related

PLSQL Problem for checking if cursor ISOPEN

What I am trying to achieve is to check if the cursor is open or not as a safety precaution but I always get this error. Any sort of help would be much appreciated.
LINE/COL ERROR
-------- -----------------------------------------------------------------
29/5 PL/SQL: SQL Statement ignored
29/5 PLS-00306: wrong number or types of arguments in call to
'WROTE_CUR'
CREATE OR REPLACE PROCEDURE print_publication (p_name CHAR) AS
CURSOR wrote_cur (v_AID NUMBER) IS
SELECT AID,PUBID FROM wrote WHERE AID = v_AID;
v_wrote_rec wrote_cur%ROWTYPE;
BEGIN
IF NOT wrote_cur%ISOPEN THEN
OPEN wrote_cur;
END IF;
CLOSE wrote_cur;
END;
/
You declared cursor with an input Argument.
CURSOR wrote_cur (v_AID NUMBER) IS --<-- Cursor is expecting argument at runtime
While in the Begin block you are not passing any argument to the cursor.
OPEN wrote_cur; --<-- Here..
pass the argument like:
OPEN wrote_cur(1);
Mistake : Forgot to pass an argument
IF NOT wrote_cur%ISOPEN THEN
OPEN wrote_cur (v_author_ID);
END IF;

PL/SQL DBMS_XMLQUERY max size

My oracle version is 11g release 2
Our system is using DBMS_XMLQUERY to transform sql result into xml, but recently the data is becoming large and we get this error: ORA-06502: PL/SQL: numeric or value error
The reason seems to be DBMS_XMLQUERY cannot handle too many records, but oracle's official document doesn't show the limitation. So maybe I have done something wrong. You can reproduce the problem in the following steps:
step1:
create table XMLDATA ( data_id int primary key, data_str
VARCHAR2(100) );
step2:
INSERT INTO XMLDATA values(1, 'test0123456789');
INSERT INTO XMLDATA values(2, 'test0123456789');
INSERT INTO XMLDATA values(3, 'test0123456789');
....
INSERT INTO XMLDATA values(500, 'test0123456789');
step3:
CREATE OR REPLACE
function test(total in int) return clob is
i int;
vn_ctx DBMS_XMLQUERY.ctxHandle;
BEGIN
vn_ctx := DBMS_XMLQUERY.NEWCONTEXT('select data_id, data_str from XMLDATA where rownum <= ' || total);
DBMS_XMLQuery.propagateOriginalException(vn_ctx,true);
DBMS_XMLQUERY.useNullAttributeIndicator(vn_ctx,true);
DBMS_XMLQUERY.SETROWTAG(vn_ctx, 'ITEM');
DBMS_XMLQUERY.SETROWSETTAG(vn_ctx, 'PODATA');
return DBMS_XMLQUERY.GETXML(vn_ctx);
END;
step4:
execute function test with a number greater than 400. Then you'll get 'ORA-06502: PL/SQL: numeric or value error'
thanks in advance
EDIT
Really sorry... I got the old code, someone adds a log statement without noticing me. The log statement can only accept a maximum of 32767 characters in one line, so the error is raised. The above function is executed by a debug tool, which gives the same error, so it's the tool's problem, not oracle.
Thanks for your answering and sorry for my naive mistakes...
I get no errors if the variable to hold the return value is big enough.
declare
rv1 clob;
rv2 varchar2(32000);
begin
rv1 := test(400); -- No error
rv2 := test(200); -- No error - returned XML is < 32000 in length.
rv2 := test(400); -- ORA-06502: PL/SQL: numeric or value error'
end;

PL/SQL Procedure is not running properly

Please consider the following code (query.sql):
create or replace function age (dateOfBirth date)
return number
is
mAge number(5,2);
begin
mAge:=(sysdate-dateOfBirth)/365.25;
return mAge;
end;
SQL> #query.sql
13
14
15 /
Warning: Function created with compilation errors.
And when I click on Show error, I get the following:
Code:
SQL> show error
Errors for FUNCTION AGE:
LINE/COL ERROR
-------- -----------------------------------------------------------------
5/8 PL/SQL: Item ignored
5/15 PLS-00325: non-integral numeric literal 5.2 is inappropriate in
this context
8/8 PL/SQL: Statement ignored
8/8 PLS-00320: the declaration of the type of this expression is
incomplete or malformed
9/5 PL/SQL: Statement ignored
9/12 PLS-00320: the declaration of the type of this expression is
incomplete or malformed
LINE/COL ERROR
-------- -----------------------------------------------------------------
I tried to do the following from : Oracle Procedure
1) SQL> set role none;
and
2) SELECT ON DBA_TAB_COLUMNS;
But the second query above is throwing error : Missing expression.
Please let me know what's wrong with all of the above stuff.
Thanks
You're missing a BEGIN and your NUMBER variable should be declared with a comma not a period.
create or replace function age (
pDateOfBirth date ) return number is
l_age number(5,2);
begin
l_age := ( sysdate - pDateOfBirth ) / 365.25;
return l_age;
end;
/
You've now edited the question to include the BEGIN but you haven't fixed your declaration of the variable. As your error message says:
PLS-00325: non-integral numeric literal 5.2 is inappropriate in this context
Personally, I believe you're calculating age incorrectly. There are 365 or 366 days in a year. I'd do this instead, which uses internal Oracle date functions:
function get_age (pDOB date) return number is
/* Return the the number of full years between
the date given and sysdate.
*/
begin
return floor(months_between(sysdate, pDOB)/12);
end;
That is if you only want the number of full years.

error when entering values by Oracle PL/SQL

I want to enter a value by console in Oracle 10g with PL SQL. I am using the web based interface and not the SQL*.
The program is like this:
DECLARE
v_desc VARCHAR2(50);
BEGIN
v_desc:=show_desc(&sv_cnumber);
DBMS_OUTPUT.PUT_LINE(v_desc);
END;
and the function is:
CREATE OR REPLACE FUNCTION show_desc
(i_course_id course.course_id%TYPE)
RETURN varchar2
AS
v_desc varchar2(50);
BEGIN
SELECT description
INTO v_desc
FROM courses
WHERE course_id=i_course_id;
RETURN v_desc;
EXCEPTION
WHEN NO_DATA_FOUND
THEN
RETURN('no description found');
END;
when I run this code, I got an error that says:
ORA-06550: line 4, column 37:
PLS-00103: Encountered the symbol "&" when expecting one of the following:
what is the mistake?
Thanks
If you want a prompt to be displayed so you can enter a value for the variable, try replacing & with colon
v_desc:=show_desc(:sv_cnumber);
& is a special symbol in PL/SQL

Function returning boolean fails on "expression is of wrong type"

I am using oracle 11g and I just cant under stand where my problem is.
I have made much more difficult stuff but I fail in this simple thing for the last 5 hr :
This is the function body
FUNCTION legal_user(
level_existance number
,types_with_impel number)
RETURN BOOLEAN
IS
v_ret_val BOOLEAN;
BEGIN
v_ret_val := FALSE;
IF (level_existance*types_with_impel>0) then
v_ret_val := TRUE;
DBMS_OUTPUT.PUT_LINE('true');
else
DBMS_OUTPUT.PUT_LINE('false');
END IF;
return v_ret_val;
END legal_user;
This is the spec :
FUNCTION legal_user(
level_existance number
,types_with_impel number)
RETURN BOOLEAN;
which does logical AND equivlant to
A*B>0?true:false;
The error message I am getting is
ORA-06552: PL/SQL: Statement ignored
ORA-06553: PLS-382: expression is of wrong type
06552. 00000 - "PL/SQL: %s"
*Cause:
*Action:
Error at Line: 1 Column: 7
This is how I run it in my IDE
SELECT compt_tree_profile_q.legal_user(1,1)
FROM dual
Pure SQL does not recognize a boolean type, although PL/SQL does. So your query does not know what datatype this function is returning..
The function works, so you could in another pl/sql block use
declare
myvar boolean;
begin
myvar := compt_tree_profile_q.legal_user(1,1);
end;
But you can't use this function in a pure select statement.
Your function returns a boolean. This datatype is known to PL/SQL, but you are using a SQL query. SQL doesn't know how to handle booleans and says "expression is of wrong type".
Regards,
Rob.
Given that you are calling this within SQL, you could use the built-in SIGN function instead of rolling your own.
The function will return -1, 0 or 1, depending on the sign of the parameter (negative, zero or positive respectively).
Here's how you would use it:
SIGN(level_existance*types_with_impel)
And how you would work it into a CASE statement:
SELECT CASE WHEN (SIGN(level_existance*types_with_impel) = 1)
THEN 'TRUE'
ELSE 'FALSE'
END legal_user
FROM ...
In this case, I'm just returning a string ('TRUE' or 'FALSE'), but you can return anything that's valid within your SELECT statement (a column, SYSDATE, etc).

Resources