SELECT id, (0 || values)::integer from test_table ORDER BY id
测试数据:
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');
CREATE OR REPLACE FUNCTION convert_to_int(text)
RETURNS int AS
$func$
BEGIN
IF $1 = '' THEN -- special case for empty string like requested
RETURN 0;
ELSE
RETURN $1::int;
END IF;
EXCEPTION WHEN OTHERS THEN
RETURN NULL; -- NULL for other invalid input
END
$func$ LANGUAGE plpgsql IMMUTABLE;
对于空字符串,返回 0 ,对于任何其他无效输入,返回 NULL . 它很容易适应 any data type conversion .
CREATE OR REPLACE FUNCTION parse_int(s TEXT) RETURNS INT AS $$
BEGIN
RETURN regexp_replace(('0' || s), '[^\d]', '', 'g')::INT;
END;
$$ LANGUAGE plpgsql;
11 回答
我自己只是在解决类似的问题,但不想要一个函数的开销 . 我想出了以下查询:
Postgres会快速调整其条件,因此你不应该让任何非整数命中你的::整数 . 它还处理NULL值(它们与regexp不匹配) .
如果你想要零而不是不选择,那么CASE语句应该有效:
您还可以创建自己的转换函数,在其中可以使用异常块:
测试:
我有同样的需求,发现这对我有用(postgres 8.4):
一些测试用例来演示:
如果需要处理字段具有非数字文本的可能性(例如“100bad”),则可以使用regexp_replace在强制转换之前删除非数字字符 .
然后像“b3ad5”这样的text / varchar值也会给出数字
为了解决Chris Cogdon对解决方案的关注,不解决所有情况,包括诸如“坏”(完全没有数字字符)之类的情况,我做了这个调整后的声明:
它的工作方式类似于更简单的解决方案,除非转换的值仅为非数字字符时给出0,例如“bad”:
这可能有点像黑客,但它在我们的案例中完成了工作:
Explanation (Tested on Postgres 8.4):
对于空字符串,上面提到的表达式为
myfield
和0
中的NULL值产生NULL
(这种确切行为可能适合您的用例,也可能不适合您的用例) .测试数据:
该查询将产生以下结果:
而仅选择
values::integer
将导致错误消息 .希望这可以帮助 .
SELECT CASE WHEN myfield="" THEN 0 ELSE myfield::integer END FROM mytable
我从未使用过PostgreSQL,但是我在manual中检查了SELECT查询中IF语句的正确语法 .
@Matthew's answer很好 . 但它可以更简单,更快捷 . 并且问题要求将空字符串(
''
)转换为0
,而不是其他"invalid input syntax"或"out of range"输入:对于空字符串,返回
0
,对于任何其他无效输入,返回NULL
.它很容易适应 any data type conversion .
输入异常块要贵得多 . 如果空字符串是常见的,那么在引发异常之前捕获该情况是有意义的 .
如果空字符串非常罕见,则将测试移动到exception子句是值得的 .
如果输入字符串中没有数字,则此函数将始终返回
0
.SELECT parse_int('test12_3test');
将返回
123
我发现以下代码简单易用 . 原始答案在这里https://www.postgresql.org/message-id/371F1510.F86C876B@sferacarta.com
希望能帮助到你
如果数据应该是整数,并且您只需要将这些值作为整数,那么为什么不进入整个里程并将列转换为整数列?
然后,您可以在将数据插入表中的系统点将非法值转换为零一次 .
通过上述转换,您强制Postgres为该表的每个查询中的每一行反复转换这些值 - 如果您对此表中的此列执行大量查询,则会严重降低性能 .
我也有同样的需求,但适用于JPA 2.0和Hibernate 5.0.2:
令人惊奇 . 我认为它也适用于LIKE .
这应该也可以完成这项工作,但这是跨越SQL而不是特定于postgres .