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) = valueAnd 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 |