我具有此功能,需要将数字与varchar进行比较。
CREATE OR REPLACE FUNCTION getOdds(i_odd in varchar2, i_id in number) return number as
begin
declare odd integer;
declare i_perecentage=0;
begin
if i_odd ='SP'
then
return (0);
end if;
odd:=round(to_number((1-i_perecentage/100)*i_odd),2);
if odd<1
then
return(i_odd);
else
return(round(odd,2));
end if;
end;
end;
/
PS:我编辑了函数,并通过比较解决了问题,现在我有另一种我不喜欢的情况。 此函数返回i_odd的计算百分比。问题是如果我在结果中的i_percentage中传递0,我得到的结果将不带小数位(例如:i_odd = 3.10和i_percentage = 0时,我的奇数= 3,但是如果我通过i_odd = 3.10和i_percentage = 1,则我的奇数= 3.10)。 为什么在i_percentage = 0上我没有获得小数位?
答案 0 :(得分:3)
如果您想将varchar2字段作为PL / SQL中的数字进行验证,通常只需尝试将其转换为数字并捕获异常即可。
CREATE OR REPLACE FUNCTION getOdds(i_odd in varchar2, i_id in number) return number as
odd number;
BEGIN
-- if i_odd = 'SP' (or another non-number), this will throw an ORA-01722
-- exception which will be caught in the exception block, below
odd := to_number(i_odd); -- you might want a format mask here
--... now you can use "odd" as a number
EXCEPTION WHEN INVALID_NUMBER THEN
return 0;
END;
/
您也可以在代码中间嵌套一个begin..end块,以捕获异常(如果更适合您):
CREATE OR REPLACE FUNCTION getOdds(i_odd in varchar2, i_id in number) return number as
odd number;
begin
begin
odd := to_number(i_odd); -- you might want a format mask here
exception when INVALID_NUMBER then
odd := 0;
end;
--... now you can use "odd" as a number
end;
/
答案 1 :(得分:3)
之所以无法捕获invalid_number异常,是因为您将输入参数声明为数字。当您调用函数时,Oracle会尝试首先将字符串转换为数字(当然,在完全输入代码之前会失败)。
如果将输入参数更改为varchar2,则转换为数字(在这种情况下是隐式的)是在函数内部完成的,并且可以根据需要捕获和处理无效数字(这里我只是返回另一个字符串)来表示问题):
create or replace function is_odd_even(i_num in varchar2)
return varchar2
is
begin
-- conversion to number is done here
if (mod(i_num, 2) = 0) then
return 'EVEN';
else
return 'ODD';
end if;
exception
when INVALID_NUMBER or VALUE_ERROR then
-- do something meaningful
return 'INV';
end;
用法示例:
with x as (
select '1' as val from dual
union all
select 'SP' as val from dual
union all
select '2' as val from dual
)
select x.val, is_odd_even(x.val)
from x;
输出:
1 ODD
SP INV
2 EVEN
答案 2 :(得分:0)
解决方案:
CREATE OR REPLACE FUNCTION getOdds(i_odd in varchar2, i_id in number) return varchar2 as
odd varchar2(10);
ret_value number(4);
begin
if (i_odd ='SP') or i_odd is null then
return 'SP';
else
odd :=ROUND( TO_NUMBER( ( 1 - (play_beting.get_odds_percentage(i_id) / 100 ) ) * TO_NUMBER(i_odd) ), 2);
IF(odd < 1) THEN
ret_value := TO_NUMBER(i_odd);
ELSE
ret_value := to_char(odd,'9999.00');
END IF;
END IF;
RETURN to_char(ret_value,'9999.00');
END getOdds;