Figuring out if a text value in SQLite is a valid integer or float#
Given a table with a TEXT
column in SQLite I want to figure out if every value in that table is actually the text representation of an integer or floating point value, so I can decide if it’s a good idea to change the type of the column (using sqlite-utils transform).
To do this efficiently, I want a SQLite idiom that will tell me if a string value is a valid integer or floating point number.
After much tinkering I’ve found two recipes for this that seem to work well.
This evaluates to true if value contains a valid integer representation:
1cast(cast(value AS INTEGER) AS TEXT) = value
And this does the same thing for floating point numbers:
1cast(cast(value AS REAL) AS TEXT) in (value, value || '.0')
The || '.0'
bit there is needed because cast('1' as REAL)
returns 1.0
, not just 1
.
(Note that 1.200
will not pass this test and will be incorrectly considered an invalid floating point representation)
Demos#
The float version:
1select2 value,3 cast(cast(value AS REAL) AS TEXT) in (value, value || '.0') as is_valid_float4from5 (6 select7 '1' as value8 union9 select10 '1.1' as value11 union12 select13 'dog' as value14 union15 select16 null as value17 )
value | is_valid_float |
---|---|
null | null |
1 | 1 |
1.1 | 1 |
dog | 0 |
The integer version:
1select2 value,3 cast(cast(value AS INTEGER) AS TEXT) = value as is_valid_int4from5 (6 select7 '1' as value8 union9 select10 '1.1' as value11 union12 select13 'dog' as value14 union15 select16 null as value17 )
value | is_valid_int |
---|---|
null | null |
1 | 1 |
1.1 | 0 |
dog | 0 |