89

Can anyone tell me the query to check whether a string is a number(double precision). It should return true if the string is number. else it should return false.

consider :

       s1 character varying;
       s2 character varying;

       s1 ='12.41212' => should return true
       s2 = 'Service' => should return false

8 Answers 8

153

I think the easiest way would be a regular expression match:

select '12.41212' ~ '^[0-9\.]+$'
=> true

select 'Service' ~ '^[0-9\.]+$'
=> false
Sign up to request clarification or add additional context in comments.

4 Comments

.123.456.789. will pass this regexp too
Postgres 8.4 when creating a view required "E"...due to error nonstandard use of escape in a string literal. Also, i had to support - or + as prefixes...so this solved those as well: select '-12.41212' ~ E'^([-+])?[0-9\.]+$';
all those results showing "1...2" as numeric
Though not initially asked by the OP, this solution will also fail strings like '1E3'.
37

I would like to propose another suggestion, since 12a345 returns true by ns16's answer.

SELECT '12.4121' ~ '^\d+(\.\d+)?$'; #true
SELECT 'ServiceS' ~ '^\d+(\.\d+)?$'; #false
SELECT '12a41212' ~ '^\d+(\.\d+)?$'; #false
SELECT '12.4121.' ~ '^\d+(\.\d+)?$'; #false
SELECT '.12.412.' ~ '^\d+(\.\d+)?$'; #false

3 Comments

add the +/- optional in front, and its perfect '^[-+]?\d+(\.\d+)?$'
paracosmo is correct with his asertation, This is a far better answer than the accepted answer.
I think the term 'is numeric' in this context should mean 'contains only digits'. The question was not 'is a number in any notational form'. Compare it for instance with the term 'alphanumeric'
22

I fixed the regular expression that a_horse_with_no_name has suggested.

SELECT '12.41212' ~ '^\d+(\.\d+)?$'; -- true
SELECT 'Service' ~ '^\d+(\.\d+)?$'; -- false

1 Comment

3-5 seems to pass your expression.
12

I've created a function to check this, using a "try catch".

The function tries to cast the text to "numeric". It returns true if the cast goes right, or return false if the cast fail.

CREATE OR REPLACE FUNCTION "sys"."isnumeric"(text)
RETURNS "pg_catalog"."bool" AS $BODY$
DECLARE x NUMERIC;
BEGIN
    x = $1::NUMERIC;
    RETURN TRUE;
EXCEPTION WHEN others THEN
    RETURN FALSE;
END;
$BODY$
  LANGUAGE 'plpgsql' IMMUTABLE STRICT  COST 100
;

ALTER FUNCTION "sys"."isnumeric"(text) OWNER TO "postgres";

2 Comments

Wow, the only answer using built-in type conversion. I just wonder if we can use type conversion without resorting to a pl/pgSQL function?
This answer works best for me because I'm coming from MS-SQL and have been used to TRY_CAST for numeric data. Glad to have a way to keep using a similar format!
8

If you want to check with exponential , +/- . then the best expression is :

^[-+]?[0-9]*\.?[0-9]+([eE][-+]?[0-9]+)?$

resulting in:

select '12.41212e-5' ~ '^[-+]?[0-9]*\.?[0-9]+([eE][-+]?[0-9]+)?$' ;

as true.

The expression is from: https://www.regular-expressions.info/floatingpoint.html

You can check for other types of numbers, for example if you expect decimal, with a sign.

 select '-12.1254' ~ '^[-+]?[0-9]*\.?[0-9]+$';

Comments

8
select s1 ~ '^\d+$';
select s2 ~ '^\d+$';

Comments

5

If you only need to accept double precision numbers, this should work fine:

select '12.41212' ~ '^\d+\.?\d+$'; -- true
select 'Service' ~ '^\d+\.?\d+$'; -- false

This would also accept integers, and negative numbers:

select '-1241212' ~ '^-?\d*\.?\d+$'; -- true

1 Comment

Regex '^\d+\.?\d+$' will not allow single digit numbers. Please use '^\d*\.?\d+$' instead
2

Building on Fernando's answer, this is a tiny bit shorter, does not need a variable to be declared and gives the exact exception type (for educational purposes):

create or replace function isnumeric(string text) returns bool as $$
begin
  perform string::numeric;
  return true;
exception
when invalid_text_representation then
  return false;
end;
$$ language plpgsql security invoker;

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.