在我的数据库中,我创建月份表,其中包含1M,2M,6M,1Q,2Q,3Q等数据(此处M =月份,Q =季度) 但我想创建一个函数,当我将1M,2M,6M称为输入时,输出仅显示1,2,6,当输入为1Q,2Q,3Q时,输出为3,6,9。
答案 0 :(得分:1)
功能:
create or replace function mq2num(i_str in varchar2) return number is
v_ret number;
begin
if i_str not like '%Q' and i_str not like '%M' then
return null;
end if;
begin
v_ret := to_number(substr(i_str, 1, length(i_str)-1));
exception when others then
return null;
end;
if i_str like '%Q' then
if v_ret not between 1 and 4 then
return null;
else
v_ret := v_ret * 3;
end if;
elsif i_str like '%M' then
if v_ret not between 1 and 12 then
return null;
end if;
else
return null;
end if;
return v_ret;
end mq2num;
如果出现问题,则返回null,例如参数错误,我不知道在这种情况下你想要什么。
测试:
with t as (
select column_value str
from table(sys.odcivarchar2list('1M', '2M', '12M', '1Q', '2Q', '3Q')))
select str, mq2num(str) mq,
case
when str like '%M' then to_number(substr(str, 1, length(str)-1))
when str like '%Q' then 3*to_number(substr(str, 1, length(str)-1))
end val
from t
STR MQ VAL
------ ---------- ----------
1M 1 1
2M 2 2
12M 12 12
1Q 3 3
2Q 6 6
3Q 9 9
如您所见,您不需要特殊功能,但功能更舒适。
答案 1 :(得分:0)
Oracle 11g R2架构设置:
CREATE FUNCTION months_and_quarters_to_months (
in_month_or_quarter VARCHAR2
) RETURN NUMBER DETERMINISTIC
AS
v_value NUMBER(2,0);
BEGIN
v_value := TO_NUMBER( SUBSTR( in_month_or_quarter, 1, LENGTH( in_month_or_quarter ) - 1 ) );
RETURN CASE UPPER( SUBSTR( in_month_or_quarter, -1 ) )
WHEN 'Q' THEN 3 * v_value
WHEN 'M' THEN v_value END;
EXCEPTION
WHEN OTHERS THEN
RETURN NULL;
END;
/
查询1 :
WITH DATA AS (
SELECT COLUMN_VALUE str
FROM TABLE(sys.odcivarchar2list('1M', '2M', '12M', '1Q', '2Q', '3Q', null, 'A', 'Q', '4Q', '12m', 'QQ')))
SELECT str,
months_and_quarters_to_months(str) mq
FROM DATA
<强> Results 强>:
| STR | MQ |
|--------|--------|
| 1M | 1 |
| 2M | 2 |
| 12M | 12 |
| 1Q | 3 |
| 2Q | 6 |
| 3Q | 9 |
| (null) | (null) |
| A | (null) |
| Q | (null) |
| 4Q | 12 |
| 12m | 12 |
| QQ | (null) |