In PostgreSQL I have a table with a varchar column. The data is supposed to be integers and I need it in integer type in a query. Some values are empty strings. The followin
The following function does
error_result
) for not castable results e.g abc
or 999999999999999999999999999999999999999999
null
as null
bigints
are compared against lower_bound
to e.g enforce positive values onlyCREATE OR REPLACE FUNCTION cast_to_bigint(text)
RETURNS BIGINT AS $$
DECLARE big_int_value BIGINT DEFAULT NULL;
DECLARE error_result BIGINT DEFAULT -1;
DECLARE lower_bound BIGINT DEFAULT 0;
BEGIN
BEGIN
big_int_value := CASE WHEN $1 IS NOT NULL THEN GREATEST(TRIM($1)::BIGINT, lower_bound) END;
EXCEPTION WHEN OTHERS THEN
big_int_value := error_result;
END;
RETURN big_int_value;
END;
This might be somewhat of a hack, but it got the job done in our case:
(0 || myfield)::integer
Explanation (Tested on Postgres 8.4):
The above mentioned expression yields NULL
for NULL-values in myfield
and 0
for empty strings (This exact behaviour may or may not fit your use case).
SELECT id, (0 || values)::integer from test_table ORDER BY id
Test data:
CREATE TABLE test_table
(
id integer NOT NULL,
description character varying,
"values" character varying,
CONSTRAINT id PRIMARY KEY (id)
)
-- Insert Test Data
INSERT INTO test_table VALUES (1, 'null', NULL);
INSERT INTO test_table VALUES (2, 'empty string', '');
INSERT INTO test_table VALUES (3, 'one', '1');
The query will yield the following result:
---------------------
|1|null |NULL|
|2|empty string|0 |
|3|one |1 |
---------------------
Whereas select only values::integer
will result in an error message.
Hope this helps.
CREATE OR REPLACE FUNCTION parse_int(s TEXT) RETURNS INT AS $$
BEGIN
RETURN regexp_replace(('0' || s), '[^\d]', '', 'g')::INT;
END;
$$ LANGUAGE plpgsql;
This function will always return 0
if there are no digits in the input string.
SELECT parse_int('test12_3test');
will return 123
You could also create your own conversion function, inside which you can use exception blocks:
CREATE OR REPLACE FUNCTION convert_to_integer(v_input text)
RETURNS INTEGER AS $$
DECLARE v_int_value INTEGER DEFAULT NULL;
BEGIN
BEGIN
v_int_value := v_input::INTEGER;
EXCEPTION WHEN OTHERS THEN
RAISE NOTICE 'Invalid integer value: "%". Returning NULL.', v_input;
RETURN NULL;
END;
RETURN v_int_value;
END;
$$ LANGUAGE plpgsql;
Testing:
=# select convert_to_integer('1234');
convert_to_integer
--------------------
1234
(1 row)
=# select convert_to_integer('');
NOTICE: Invalid integer value: "". Returning NULL.
convert_to_integer
--------------------
(1 row)
=# select convert_to_integer('chicken');
NOTICE: Invalid integer value: "chicken". Returning NULL.
convert_to_integer
--------------------
(1 row)
SUBSTRING may help for some cases, you can limit the size of the int.
SELECT CAST(SUBSTRING('X12312333333333', '([\d]{1,9})') AS integer);
I also have the same need but that works with JPA 2.0 and Hibernate 5.0.2:
SELECT p FROM MatchProfile p WHERE CONCAT(p.id, '') = :keyword
Works wonders. I think it works with LIKE too.