暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

Postgresql扩展实现Oracle自带NVL函数功能

SmallDB 2025-04-15
551

 

总结

数据库迁移的过程中,肯定有很多数据库的特性小功能是在线上使用的,这个迁移过程需要考虑在内,迁移不迁移这个小特性是一个权衡的问题,如果问题只有几个开发人员评估之后愿意改,这个叫没有问题,可是遇到一个功能已经流转了很多开发人员,大家也说不清楚这个功能的时候,这个时候一般开发是不愿意动的,这个就需要迁移数据的时候,需要数据库来支持这个特性,我们可以通过个这次的本小结来学习如何实现这个功能
如果不知道如何开始写扩展可以参考我之前的文章

示例数据

-- 假设我们有一个表 test_table,包含两列 id 和 value
CREATE TABLE test_table (
    id NUMBER PRIMARY KEY,
    value NUMBER
);
-- 插入一些数据
INSERT INTO test_table (id, valueVALUES (1NULL), (210), (320);

优化前(有空值)
postgres=# SELECT id, value AS new_value FROM test_table;
 id | new_value
----+-----------
  1 |
  2 |        10
  3 |        20
(3 rows)

方式1 修改程序通过coalesce函数处理

后优化
postgres=# SELECT id, coalesce(value, 0) AS new_value FROM test_table;
 id | new_value
----+-----------
  1 |         0
  2 |        10
  3 |        20
(3 rows)

postgres=#

方式2 写一个函数

create or replace function nvl (anyelement, anyelement)
returns anyelement language sql as $$
    select coalesce($1, $2)
$$;

优化后
postgres=# SELECT id, nvl(value, 0) AS new_value FROM test_table;
 id | new_value
----+-----------
  1 |         0
  2 |        10
  3 |        20
(3 rows)

postgres=#

方式3 通过扩展函数(可以实现大量ORACLE功能特性迁移)

PG_FUNCTION_INFO_V1(ora_nvl);

Datum 
ora_nvl(PG_FUNCTION_ARGS)
{
    if (!PG_ARGISNULL(0))
        PG_RETURN_DATUM(PG_GETARG_DATUM(0));

    if (!PG_ARGISNULL(1))
        PG_RETURN_DATUM(PG_GETARG_DATUM(1));

    PG_RETURN_NULL();
}

CREATE FUNCTION ora_nvl(anyelement, anyelement)
RETURNS anyelement
AS 'pg_hello_world','ora_nvl'
LANGUAGE C IMMUTABLE PARALLEL SAFE;

优化后
postgres=# SELECT id, ora_nvl(value, 0) AS new_value FROM test_table;
 id | new_value
----+-----------
  1 |         0
  2 |        10
  3 |        20
(3 rows)

postgres=#

源码
https://gitee.com/smalldba/utilitiy/blob/master/postgresql/pg_hello_world/pg_hello_world.c

 


文章转载自SmallDB,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论