plpgsql:函数内部的奇怪隐式转换

时间:2013-03-27 22:44:43

标签: function postgresql casting plpgsql

我正在使用PostgreSQL 8.1。

我对这个函数中隐式转换的内容感到不安:

CREATE OR REPLACE FUNCTION this_is_weird(v_input TEXT)
RETURNS TEXT AS $$
BEGIN
        IF v_input > 113 THEN
                RETURN 'answer1';
        ELSE
                RETURN 'answer2';
        END IF;
END;
$$ LANGUAGE plpgsql;

输入'17'(作为字符串)给出返回值'answer1'。但如果我输入

SELECT '17' > 113

在psql中,我得到'f'

(我当然可以通过添加显式强制转换v_input::integer来解决问题。)

1 个答案:

答案 0 :(得分:2)

lexical 比较中,17 大于113

regress=> SELECT '17' > '113';
?column? 
----------
 t
(1 row)

如果要进行数字比较,请不要进行文本比较。

因为您正在将文本值与数字进行比较,所以将数字转换为文本并将其作为文本进行比较。你的代码“工作”(即运行没有错误),因为它依赖于非常旧的PostgreSQL版本中的错误,其中服务器将隐式地将操作数转换为需要的文本。这证明可以掩盖应用程序错误,并且可以很容易地编写静默不正确的代码,因此在8.3中删除了隐式转换。有关该主题的一些信息,请参阅Peter's blog entry

在PostgreSQL 8.3及更高版本中,您的代码会产生错误。

您需要计划升级,从长远来看,它会为您节省时间和麻烦,原因有很多种。删除max_fsm_pages以支持自动调整;能见度图;大大改善了autovacuum; ...即使您不需要性能改进,升级也有很多好处。阅读每个主要版本(8.2.0,8.3.0等)的发行说明,了解升级和兼容性建议。