declare
l_tot number := 0;
begin
for i in 1..apex_application.g_f08.count loop
l_tot := l_tot + nvl(to_number(apex_application.g_f08(i)),0);
end loop;
if l_tot = nvl(to_number(:P21_TOTAL_PRICE),0) then
return true;
else
return false;
end if;
end;
Got below error with above code
ORA-06502: PL/SQL: numeric or value error: character to number conversion error
Error occurred with :P21_TOTAL_PRICE. What is the wrong ? How can i correct this ?
Rather than using REPLACE you should use the more powerful REGEXP_REPLACE function. http://www.orafaq.com/wiki/REGEXP_REPLACE
You can then remove any non-numeric character from the string before then using the TO_NUMBER function.
In your case it would be something like:
REGEXP_REPLACE(:P21_TOTAL_PRICE, '[^0-9]+', '');
See my answer to almost the exact same question here: Oracle To_Char function How to handle if it's already a string
The error rises because the number that you're representing is actually a character string involving commas etc. When you put a to_number to that, Oracle cannot replace the commas.
You might want to use replace function to strip off the commas
Change
if l_tot = nvl(to_number(:P21_TOTAL_PRICE),0) then
to
if l_tot = nvl(to_number(replace(:P21_TOTAL_PRICE,',','')),0) then
Related
CASE WHEN (r.code_value4 = 0 AND LENGTH(ltrim(rtrim(xx.AFFILIATE_CODE))) > 0) AND
r_intercompany.code_value1 is not null AND
ltrim(rtrim(xx.AFFILIATE_CODE)) <> (CASE WHEN xx.COMPANY_CODE_JE_EXCEPTION_FLAG = 1
THEN r.code_value3 ELSE r.code_value1 END)
THEN r_intercompany.code_value1
ELSE NVL(r_mga_acct.code_value2, xx.ACCOUNT_NUMBER) END
I have view in which the above part of the sql is being used in select statement and as well as to compare with a field while joining. When I run the view after making this change, it is throwing the error ORA-01722 invalid number.
Please let me know on how to correct this.
Thanks
" it is throwing the error ORA-01722 invalid number."
It is likely somewhere you are comparing a numeric column with a string column . Oracle is implicitly casting the string to a number but the column contains values which cannot be converted, so it hurls.
"Please let me know on how to correct this."
Don't rely on implicit data conversion. Go through your code, check the data types of all the columns. Where you find a varchar2 column being compared to a number you need to cast the number to a string. For literals that means quoting them - '1' instead of 1 - and for columns that means wrapping them in to_char() calls.
My Suspicion is either r.code_value4 field or xx.COMPANY_CODE_JE_EXCEPTION_FLAG field is String type hence try the below
CASE WHEN (r.code_value4 = '0' AND LENGTH(ltrim(rtrim(xx.AFFILIATE_CODE))) > 0) AND
r_intercompany.code_value1 is not null AND
ltrim(rtrim(xx.AFFILIATE_CODE)) <> (CASE WHEN xx.COMPANY_CODE_JE_EXCEPTION_FLAG = '1'
THEN r.code_value3 ELSE r.code_value1 END)
THEN r_intercompany.code_value1
ELSE NVL(r_mga_acct.code_value2, xx.ACCOUNT_NUMBER) END
I am using ireport 3.7.1. I have made a connection with my database.I have a procedure which when given an input in number ,it returns the word format of the number i.e if I give input 10,it will return ten. The problem is when I am executing the procedure in pl/sql developer,I am getting the proper output but when I am firing the same procedure in ireport it's giving me this exception
Cannot cast object '(10)' with class 'java.lang.String' to class 'java.lang.Integer' .
Casting straight from a String to an Integer is not possible. You'll want to use the function Integer.parseInt(stringNumber);
(10) isn't a properly formated integer. Not even for PL/SQL:
select '(10)' +0 from dual;
> ORA-01722: invalid number
I could only suggest you to trace back the point where those ( ) come from. And fix your code at that position instead. Just a wild guess, some number formats use parenthesis to represent negative numbers. Maybe this is your case?
That being said, if you still want to locally remove the parenthesis that have somehow lurked inside of your string:
String str = "(10)";
int value = Integer.parseInt(str.substring(1, str.length()-1));
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
// *blindly* get away of first and last character
// assuming those are `(` and `)`
For something a little bit more robust, and assuming parenthesis denotes negative numbers, you should try some regex:
String str = "(10)";
str = str.replaceFirst("\\(([0-9]+)\\)", "-$1");
// ^^^ ^^^ ^
// replace integer between parenthesis by its negative value
// i.e.: "(10)" become "-10" (as a *string*)
int value = Integer.parseInt(str);
Reading this Pascal BNF grammar I can't understand why is a ; required to appear after end in a function definition. After a function-heading is seen, a function-block that's block may appear:
function-declaration =
function-heading ";" function-body |
function-heading ";" directive |
function-identification ";" function-body .
function-body =
block .
When a begin appear, that's part of a statement-par, that's part of a block, it's processed by statement-part, right?
block =
declaration-part statement-part .
statement-part =
begin statement-sequence end .
Note statement-part. There's no ; here after end keyword and this is not part of a statement-sequence. So, I don't get how the compiler claims about lack of ; after end keyword, like in this example:
function myabs(i : integer) : integer;
begin
if i < 0 then begin i := -i; end; < -- it's process by statement-sequence, so, ';' may appear
myabs := i;
end; <-- it is the semicolon what about I'm speaking
What am I missing? am I reading wrong the grammar? all Pascal compilers I've tried give an error if I omit this.
ANTLRWorks is your best friend here.
If you try some pascal grammar such as http://www.monperrus.net/martin/pascal-antlr3 using antlrworks (http://www.antlr3.org/works/) you'll see that a program like
program first;
function myabs(i : integer) : integer;
begin
end;
begin
end.
will be parsed like this
so you can see exactly what's happening.
ps. the pascal grammar link I've provided to you has a problem with one specific token, but I bet you can workaround this ;-)
ps2. update - antlrworks screenshot to help #Jack
You don't have to have a semi-colon after an end. Simple as that.
Semi-colon is used to separate statements. So you only need to have a semi-colon after an end if it is not the last statement. If it is the last statement you should instead have a full stop.
Now, there could also be some error in the BNF that means that according to the BNF you don't have to have a semi-colon where you actually need it, but the only way to figure that out is to analyze the whole BFN in detail, which I don't feel is constructive. :-)
But in this case I think what you have missed is that a procedure or function declaration must end with a semi-colon.
Procedure and functions do not need to be terminated with a semi-colon, but they must be separated by one:
From the Pascal BNF
proc-and-func-declaration:
proc-or-func
proc-and-func-declaration ; proc-or-func
I am working with a pl/sql procedure. I have an initialized variable myvar and I want to check its value : if it does not contain 'Z', I want it to contain 'P'.
I am currently doing it this way:
myvar := decode(myvar,'Z','Z','P');
I was just wondering if there was a simplier way to do this. I mean, decode is already simple, but I feel it's weird to specify the content of the variable while it is already in it !
If such a function would exist, it would look like this:
Function myfunction(a In Varchar2, b In Varchar2, c In Varchar2)
Return Varchar2
Is
Begin
if a <> b
then
return c;
end if;
return a;
End myfunction;
Any help would be appreciated !
There is no built-in function that does exactly what you want.
You could use CASE rather than DECODE:
CASE myvar WHEN 'Z' THEN 'Z' ELSE 'P' END
It doesn't make it any shorter though!
Put that function of yours to the program's declaration section and use it!
I agree the best option is to use CASE expression:
CASE myvar WHEN 'Z' THEN 'Z' ELSE 'P' END
Another approach if you feel happy with DECODE is to run this query:
SELECT decode(myvar,'Z','Z','P')
INTO myvar
FROM DUAL;
To answer your original question of whether there is a simpler way, there is also this:
if myvar <> 'Z' then
myvar := 'P'
end if;
I have an oracle function which is given below. when I run this in sql-developer it gives an error
ORA-06502: PL/SQL: numeric or value error: character string buffer too
small error.
However the DBMS_OUTPUT.PUT_LINE(FINAL_RESULT) line in the function is printing the expected output in the output window.
Can anyone help me in this??
create or replace
FUNCTION AVERAGE_WORKFORCE(PERIOD in varchar2, YR in varchar2) RETURN CLOB AS
FINAL_RESULT CLOB:=null;
STRING_QUERY_TEXT CLOB:=null;
OUTPUT_RESULT CLOB:=null;
BEGIN
FINAL_RESULT:='<FINAL_RESULT><HEADER><NAME> </NAME> <NAME>SENIOR DIRECTOR</NAME> <NAME>DIRECTOR</NAME> <NAME>EXECUTIVE</NAME> <NAME>MANAGER</NAME><NAME>CASHIER</NAME><NAME>EMPLOYEE</NAME></HEADER>';
STRING_QUERY_TEXT:='SELECT XMLElement("tuple",XMLElement("DESC",''Average number of registered employees''), XMLElement("PERMANENT_EMP",GET_COUNT_AVERAGE_WORKFORCE('''||PERIOD||''','''||YR||''',''SENIOR DIRECTOR'')), XMLElement("PERMANENT_EMP",GET_COUNT_AVERAGE_WORKFORCE('''||PERIOD||''','''||YR||''',''DIRECTOR'')), XMLElement("PERMANENT_EMP",GET_COUNT_AVERAGE_WORKFORCE('''||PERIOD||''','''||YR||''',''MANAGER'')), XMLElement("PERMANENT_EMP",GET_COUNT_AVERAGE_WORKFORCE('''||PERIOD||''','''||YR||''',''EXECUTIVE'')), XMLElement("PERMANENT_EMP",GET_COUNT_AVERAGE_WORKFORCE('''||PERIOD||''','''||YR||''',''CASHIER'')), XMLElement("PERMANENT_EMP",GET_COUNT_AVERAGE_WORKFORCE('''||PERIOD||''','''||YR||''',''EMPLOYEE''))) FROM DUAL';
EXECUTE_QUERY_RETURN_RESULT(STRING_QUERY_TEXT,OUTPUT_RESULT);
FINAL_RESULT:=FINAL_RESULT||''||OUTPUT_RESULT;
FINAL_RESULT:=FINAL_RESULT||''||'</FINAL_RESULT>';
DBMS_OUTPUT.PUT_LINE(FINAL_RESULT);
RETURN FINAL_RESULT;
END AVERAGE_WORKFORCE;
With apologies to Alex and Tony (who have obviously thought the same thing).
Your code is showing the expected output so the DBMS_OUTPUT line must have succeeded.
DBMS_OUTPUT.PUT_LINE(FINAL_RESULT);
QED the exception is happening after this point. We have one more line in the function.
RETURN FINAL_RESULT;
An educated guess is that the problem is as Alex mentions - the result is too big for the variable defined in the calling code in SQL Developer (i.e. it is not a CLOB, but a string that is too small for the result).
If this is generated code, it may be a bug with SQL Developer and CLOB functions.
Have you tried doing a SELECT function FROM DUAL instead?
Try this DBMS_OUTPUT.ENABLE(200000);
The easiest fix is to limit the line length to 255 characters by inserting some newlines. See this.