Sql 我需要只显示varchar2数据类型列中的数值,而不使用任何正则表达式
表名SAMP_TAB-它只有一个数据类型为varchar2的列COL-数据如下:Sql 我需要只显示varchar2数据类型列中的数值,而不使用任何正则表达式,sql,oracle,Sql,Oracle,表名SAMP_TAB-它只有一个数据类型为varchar2的列COL-数据如下: COL ---- 1234 abcd 098 12wer 345 这些是该列中的上述示例值 现在我想写一个查询,它将只从这个列返回数值 期望输出: 1234 098 345 我想在不使用任何正则表达式的情况下编写该查询。假设您由于某种原因无法使用正则表达式: SELECT COL FROM SAMP_TAB WHERE TRIM(TRANSLATE(COL, '0123456789', ' ')) IS NU
COL
----
1234
abcd
098
12wer
345
这些是该列中的上述示例值
现在我想写一个查询,它将只从这个列返回数值
期望输出:
1234
098
345
我想在不使用任何正则表达式的情况下编写该查询。假设您由于某种原因无法使用正则表达式:
SELECT COL
FROM SAMP_TAB
WHERE TRIM(TRANSLATE(COL, '0123456789', ' ')) IS NULL;
如果您可以使用regex,那么将REGEXP_与模式^[0-9]+$一起使用:
或者:
SQL> with test (col) as
2 (select '1234' from dual union all
3 select 'abcd' from dual union all
4 select '098' from dual union all
5 select '12wer' from dual union all
6 select '1ab3' from dual union all
7 select '345' from dual
8 )
9 select col
10 from test
11 where translate(col, 'a0123456789', 'a') is null;
COL
-----
1234
098
345
SQL>
拆分每个字符,通过ascii函数过滤提取整数 ascii介于48和57之间,重新组合字符串可能是另一种选择:
with t as
(
select substr(col,level,1) as chr, level as lvl,
row_number() over (order by 0) as rn
from samp_tab
connect by level <= length(col)
and prior sys_guid() is not null
and prior col = col
), t2 as
(
select t.*, sum(case when lvl=1 then 1 else 0 end) over (order by rn) as rn2
from t
where ascii(chr) between 48 and 57
)
select listagg(chr) within group (order by rn2) as new_col
from t2
group by rn2;
如果您使用的是12c R2或更高版本,并且应该使用,则可以使用内置函数validate_conversion,这是确定值是否可以转换为其他数据类型的安全方法 像这样:
select * from samp_table
where validate_conversion(col as number) = 1
/
与使用regex或translate的解决方案相比,这种方法有一个主要优势,即它测试字符串的计算结果是否为数值,而其他解决方案则会阻塞,例如,1.234E+10这样的指数表达式。或者可能传递一个IP地址,如127.0.0.1
如果您使用的是Oracle的早期版本,则可以编写一个用户定义的函数,该函数用于计算传递的参数:
create or replace function is_number (p_str in varchar2) return pls_integer
is
rv pls_integer;
begin
declare
n number;
begin
n := to_number(p_str);
rv := 1; -- p_str is a number
exception
when others then
rv := 0; -- p_str is not a number
end;
return rv;
end;
/
您可以在WHERE子句中调用此函数,与上面示例中的validate_conversion相同。OP在没有使用任何reg-exp的情况下说的。我觉得这个要求有点可疑。为什么OP不想使用正则表达式,因为这是处理此需求的最佳方法,除非是家庭作业问题等?请参阅下面的@APC答案。至于fishy,我认为家庭作业可以解释这一点-
create or replace function is_number (p_str in varchar2) return pls_integer
is
rv pls_integer;
begin
declare
n number;
begin
n := to_number(p_str);
rv := 1; -- p_str is a number
exception
when others then
rv := 0; -- p_str is not a number
end;
return rv;
end;
/