将Oracle NVL移植到Postgres Coalesce失败

时间:2013-06-19 23:36:06

标签: postgresql-9.2

我正在将旧的Oracle代码移植到PostgreSQL 9.2。有几百个对Oracle NVL()的调用,所以我创建了映射函数来提供等效的功能。这个应该是微不足道的,但是由于对我来说根本不明显的原因而失败。

CREATE OR REPLACE FUNCTION nvl(expr1 text, expr2 text)
  RETURNS text AS
$BODY$
BEGIN
  RETURN COALESCE( expr1, expr2 );
END;
$BODY$
  LANGUAGE plpgsql STRICT IMMUTABLE;

我为不同的输入参数类型定义了NVL的变体,但是为了测试,我删除了除此之外的所有内容。我确定这个被调用,因为如果我删除它,我会得到一个未知的函数错误。

以下是此数据库上几个查询的结果,说明了问题。

# select nvl(null, 'N/A');
 nvl 
-----

(1 row)

# select coalesce(nvl(null, 'N/A'), 'ITS STILL NULL???');
     coalesce      
-------------------
 ITS STILL NULL???
(1 row)

从上面可以看出,coalesce很好地独立,但不是我的功能。

我正在使用最新版本的PostgreSQL:

# select version();
PostgreSQL 9.2.4 on x86_64-unknown-linux-gnu, compiled by gcc (GCC) 4.4.7 20120
313 (Red Hat 4.4.7-3), 64-bit

任何线索?

2 个答案:

答案 0 :(得分:3)

这种简单的函数应该在可能的情况下用SQL语言实现。你可以获得更好的表现:

CREATE OR REPLACE FUNCTION nvl(expr1 text, expr2 text)
  RETURNS text AS
$BODY$
  SELECT coalesce($1, $2);
$BODY$
  LANGUAGE sql;

答案 1 :(得分:2)

问题是我的函数在函数定义的末尾有 STRICT IMMUTABLE。我把它从原始帖子中删除了,但已编辑它以显示这些参数。

STRICT导致函数在其中一个参数为null时始终返回null。在这种情况下,我不希望这样,因为期望此函数在内部测试null并适当地响应。

这就是我使用剪切和粘贴的代码模板而不完全理解它们的作用。