【问题标题】:Extract number from string with Oracle function使用Oracle函数从字符串中提取数字
【发布时间】:2026-02-03 00:25:01
【问题描述】:

我需要创建一个以字符串为参数的 Oracle DB 函数。该字符串包含字母和数字。我需要从这个字符串中提取所有数字。例如,如果我有一个像 RO1234 这样的字符串,我需要能够使用一个函数,比如 extract_number('RO1234'),结果将是 1234

更准确地说,这是使用此函数的 SQL 查询类型。

SELECT DISTINCT column_name, extract_number(column_name) 
FROM table_name
WHERE extract_number(column_name) = 1234;

问题:如何使用 Oracle SQL Developer 或 SQLTools 客户端应用程序向我的 Oracle 数据库添加类似的功能,以便能够像上面的示例一样使用它?

【问题讨论】:

  • 你可以使用内置函数regex_replaceSELECT REGEXP_REPLACE(column_name,'[[:alpha:]]') from tbl,至少你应该在谷歌中搜索,看到这个(community.oracle.com/thread/598281)oracle社区提供了一些有用的方法
  • 我可以举一个很好的例子。我不擅长甲骨文
  • “我需要从这个字符串中提取所有数字” - 如果输入字符串包含多个数字会发生什么?例如。你的函数应该为输入“1234abc5678”返回什么?
  • @FrankSchmitt,鉴于存储在该列上的值的格式,无需考虑这种可能性。
  • 您的示例查询似乎有错误,即 table_name 周围的单引号(也可能在 column_name 周围不正确)。另外,当您已经确切知道它是什么时,为什么还要在列列表中包含提取的数字,因为您已在 WHERE 条件中指定它?

标签: sql oracle oracle11g oracle-sqldeveloper sqltools


【解决方案1】:

您可以使用REGEXP_REPLACE 来删除字符串中的所有非数字字符:

select regexp_replace(column_name, '[^0-9]', '')
from mytable;

select regexp_replace(column_name, '[^[:digit:]]', '')
from mytable;

当然你可以写一个函数extract_number。不过,编写一个只包含一个函数调用本身的函数似乎有点矫枉过正。

create function extract_number(in_number varchar2) return varchar2 is
begin
  return regexp_replace(in_number, '[^[:digit:]]', '');
end; 

【讨论】:

  • 我不需要修改sql查询,我需要那个我可以调用的函数
  • REGEXP_REPLACE 你要调用的函数来提取数字。
  • 但是,我已经添加了您可以编写的函数来为您调用regexp_replace
  • 是的,Overkill 是我的另一个名字。谢谢。
  • @ABHISHEK D:你在找select regexp_replace(column_name, '[^0-9]', '') as my_numeric_value from mytable;吗?
【解决方案2】:

您可以使用正则表达式从字符串中提取数字。让我们检查一下。假设这是混合文本和数字“stack12345overflow569”的字符串。这个应该可以:

select regexp_replace('stack12345overflow569', '[[:alpha:]]|_') as numbers from dual;

这将返回“12345569”。

你也可以使用这个:

select regexp_replace('stack12345overflow569', '[^0-9]', '') as numbers,
       regexp_replace('Stack12345OverFlow569', '[^a-z and ^A-Z]', '') as characters
from dual

对于数字返回“12345569”,对于字符返回“*”。

【讨论】:

  • 这仍然返回文本(字符类型),而不是数字。将其放在问题中显示的示例查询中也会使答案受益。
【解决方案3】:

这对我有用,我只需要字符串中的第一个数字:

TO_NUMBER(regexp_substr(h.HIST_OBSE, '\.*[[:digit:]]+\.*[[:digit:]]*'))

该字段具有以下字符串:"(43 Paginas) REGLAS DE PARTICIPACION"

结果字段:43

【讨论】:

  • 提取字符串中第一组数字的更简单方法是 select regexp_substr(h.HIST_OBSE,'[0-9]+','')
【解决方案4】:

如果您正在寻找带小数的第一个数字,因为字符串具有正确的小数位,您可以尝试regexp_substr 函数,如下所示:

regexp_substr('stack12.345overflow', '\.*[[:digit:]]+\.*[[:digit:]]*')

【讨论】:

  • 这有一个错字(文本周围的单引号加倍)并且仍然返回文本(字符类型),而不是数字。将其放在问题中显示的示例查询中也会使答案受益。
【解决方案5】:

为了从字符串“A0807”中提取月份和年份,我在 PL/SQL 中执行了以下操作:

DECLARE
    lv_promo_code VARCHAR2(10) := 'A0807X';
    lv_promo_num VARCHAR2(5);
    lv_promo_month NUMBER(4);
    lv_promo_year NUMBER(4);
    BEGIN
    lv_promo_num := REGEXP_SUBSTR(lv_promo_code, '(\d)(\d)(\d)(\d)');

lv_promo_month := EXTRACT(month from to_date(lv_promo_num, 'MMYY'));
DBMS_OUTPUT.PUT_LINE(lv_promo_month);
lv_promo_year := EXTRACT(year from to_date(lv_promo_num, 'MMYY'));
DBMS_OUTPUT.PUT_LINE(lv_promo_year);
END;

【讨论】: