check if “it's a number” function in Oracle

后端 未结 16 2599
一整个雨季
一整个雨季 2020-11-28 10:31

I\'m trying to check if a value from a column in an oracle (10g) query is a number in order to compare it. Something like:

select case when ( is_number(myTab         


        
相关标签:
16条回答
  • 2020-11-28 11:06

    Note that regexp or function approaches are several times slower than plain sql condition.

    So some heuristic workarounds with limited applicability make sence for huge scans.

    There is a solution for cases when you know for sure that non-numeric values would contain some alphabetic letters:

    select case when upper(dummy)=lower(dummy) then '~numeric' else '~alpabetic' end from dual
    

    And if you know some letter would be always present in non-numeric cases:

    select case when instr(dummy, 'X')>0 then '~alpabetic' else '~numeric' end from dual
    

    When numeric cases would always contain zero:

    select case when instr(dummy, '0')=0 then '~alpabetic' else '~numeric' end from dual
    
    0 讨论(0)
  • 2020-11-28 11:08

    @JustinCave - The "when value_error" replacement for "when others" is a nice refinement to your approach above. This slight additional tweak, while conceptually the same, removes the requirement for the definition of and consequent memory allocation to your l_num variable:

    function validNumber(vSomeValue IN varchar2)
         return varchar2 DETERMINISTIC PARALLEL_ENABLE
         is
    begin
      return case when abs(vSomeValue) >= 0 then 'T' end;
    exception
      when value_error then
        return 'F';
    end;
    

    Just a note also to anyone preferring to emulate Oracle number format logic using the "riskier" REGEXP approach, please don't forget to consider NLS_NUMERIC_CHARACTERS and NLS_TERRITORY.

    0 讨论(0)
  • 2020-11-28 11:10

    I'm against using when others so I would use (returning an "boolean integer" due to SQL not suppporting booleans)

    create or replace function is_number(param in varchar2) return integer
     is
       ret number;
     begin
        ret := to_number(param);
        return 1; --true
     exception
        when invalid_number then return 0;
     end;
    

    In the SQL call you would use something like

    select case when ( is_number(myTable.id)=1 and (myTable.id >'0') ) 
                then 'Is a number greater than 0' 
                else 'it is not a number or is not greater than 0' 
           end as valuetype  
      from table myTable
    
    0 讨论(0)
  • 2020-11-28 11:11

    This is a potential duplicate of Finding rows that don't contain numeric data in Oracle. Also see: How can I determine if a string is numeric in SQL?.

    Here's a solution based on Michael Durrant's that works for integers.

    SELECT foo
    FROM bar
    WHERE DECODE(TRIM(TRANSLATE(your_number,'0123456789',' ')), NULL, 'number','contains char') = 'number'
    

    Adrian Carneiro posted a solution that works for decimals and others. However, as Justin Cave pointed out, this will incorrectly classify strings like '123.45.23.234' or '131+234'.

    SELECT foo
    FROM bar
    WHERE DECODE(TRIM(TRANSLATE(your_number,'+-.0123456789',' ')), NULL, 'number','contains char') = 'number'
    

    If you need a solution without PL/SQL or REGEXP_LIKE, this may help.

    0 讨论(0)
提交回复
热议问题