GaussDB数据库SQL系列:函数重载技术深度解析

GaussDB数据库SQL系列:函数重载技术深度解析

一、函数重载的核心价值

1.1 多态性实现
​​参数差异化处理​​:同一函数名适配不同参数类型(如整数/字符串处理)
​​接口统一化​​:提供一致的调用方式(如calculate()同时处理金额和数量)
​​代码复用增强​​:避免创建多个功能相似的函数(如不同数据类型的校验逻辑)
1.2 典型应用场景
场景 实现方式 业务价值
数值类型适配 重载处理INT/DECIMAL/BIGINT 统一数值计算接口
数据格式转换 重载处理JSON/TEXT/CSV输入 简化异构数据接入
动态参数控制 重载不同参数数量的版本 灵活应对业务规则变化

二、重载函数定义语法

  1. 参数数量重载
-- 整数版本
CREATE OR REPLACE FUNCTION calculate(
  a INT, 
  b INT
) RETURNS INT AS $$
BEGIN
  RETURN a * b;
END;
$$ LANGUAGE plpgsql;

-- 字符串版本
CREATE OR REPLACE FUNCTION calculate(
  a VARCHAR, 
  b VARCHAR
) RETURNS VARCHAR AS $$
BEGIN
  RETURN CONCAT(a, '_', b);
END;
$$ LANGUAGE plpgsql;

-- 调用示例
SELECT calculate(3,5);       -- 输出15
SELECT calculate('A','B');   -- 输出A_B
  1. 参数类型重载
-- 数值计算版本
CREATE OR REPLACE FUNCTION discount(
  price NUMERIC,
  rate NUMERIC
) RETURNS NUMERIC AS $$
BEGIN
  RETURN price * (1 - rate);
END;
$$ LANGUAGE plpgsql;

-- 百分比字符串版本
CREATE OR REPLACE FUNCTION discount(
  price NUMERIC,
  rate VARCHAR
) RETURNS NUMERIC AS $$
DECLARE 
  rate_num NUMERIC;
BEGIN
  rate_num := REPLACE(rate, '%', '')::NUMERIC / 100;
  RETURN price * (1 - rate_num);
END;
$$ LANGUAGE plpgsql;

-- 调用示例
SELECT discount(100.0, 0.2);    -- 输出80.0
SELECT discount(100.0, '20%');  -- 输出80.0
  1. 参数顺序重载
-- 先时间后金额版本
CREATE OR REPLACE FUNCTION process_transaction(
  trans_time TIMESTAMPTZ,
  amount NUMERIC
) RETURNS BOOLEAN AS $$
BEGIN
  INSERT INTO transactions (time, amt)
  VALUES (trans_time, amount);
  RETURN TRUE;
END;
$$ LANGUAGE plpgsql;

-- 先金额后时间版本
CREATE OR REPLACE FUNCTION process_transaction(
  amount NUMERIC,
  trans_time TIMESTAMPTZ
) RETURNS BOOLEAN AS $$
BEGIN
  INSERT INTO transactions (amt, time)
  VALUES (amount, trans_time);
  RETURN TRUE;
END;
$$ LANGUAGE plpgsql;

-- 调用示例
SELECT process_transaction(NOW(), 500.0);  -- 参数顺序(时间,金额)
SELECT process_transaction(500.0, NOW());  -- 参数顺序(金额,时间)

三、高级应用技巧

  1. 结合类型转换的重载
-- 自动类型推断版本
CREATE OR REPLACE FUNCTION parse_value(input TEXT)
RETURNS ANYELEMENT AS $$
BEGIN
  RETURN input::NUMERIC;
EXCEPTION WHEN OTHERS THEN
  RETURN input::VARCHAR;
END;
$$ LANGUAGE plpgsql;

-- 显式类型指定版本
CREATE OR REPLACE FUNCTION parse_value(
  input TEXT,
  output_type VARCHAR DEFAULT 'NUMERIC'
) RETURNS ANYELEMENT AS $$
BEGIN
  IF output_type = 'NUMERIC' THEN
    RETURN input::NUMERIC;
  ELSIF output_type = 'VARCHAR' THEN
    RETURN input::VARCHAR;
  END IF;
END;
$$ LANGUAGE plpgsql;

-- 智能调用示例
SELECT parse_value('123.45');                 -- 自动转为123.45
SELECT parse_value('ABC', 'VARCHAR');         -- 强制转为字符串
  1. 递归重载实现树形结构
-- 基础节点处理版本
CREATE OR REPLACE FUNCTION process_node(node_id INT)
RETURNS TABLE (level INT, node_name VARCHAR) AS $$
BEGIN
  RETURN QUERY 
  SELECT 1, name FROM tree WHERE id = node_id;
  
  RETURN QUERY 
  SELECT n.level + 1, c.name
  FROM tree c
  JOIN process_node(n.node_id) n ON c.parent_id = n.node_id;
END;
$$ LANGUAGE plpgsql;

-- 带过滤条件的重载版本
CREATE OR REPLACE FUNCTION process_node(
  node_id INT,
  min_level INT DEFAULT 1
) RETURNS TABLE (level INT, node_name VARCHAR) AS $$
BEGIN
  RETURN QUERY 
  SELECT * FROM process_node(node_id)
  WHERE level >= min_level;
END;
$$ LANGUAGE plpgsql;

-- 调用示例
SELECT * FROM process_node(1001);           -- 默认从根节点开始
SELECT * FROM process_node(1001, 3);        -- 只显示第三层以下节点

四、性能优化策略

  1. 执行计划差异化
-- 创建带统计信息的重载函数
CREATE OR REPLACE FUNCTION fast_sum(numbers INT[])
RETURNS INT AS $$
DECLARE
  total INT := 0;
BEGIN
  FOR i IN 1..array_length(numbers,1) LOOP
    total := total + numbers[i];
  END LOOP;
  RETURN total;
END;
$$ LANGUAGE plpgsql
SET enable_seqscan = off;

-- 创建并行版本
CREATE OR REPLACE FUNCTION parallel_sum(numbers INT[])
RETURNS INT AS $$
BEGIN
  RETURN (SELECT SUM(num) FROM unnest(numbers) AS num);
END;
$$ LANGUAGE plpgsql
SET max_parallel_workers_per_gather = 4;

-- 智能选择示例
EXPLAIN ANALYZE SELECT fast_sum(ARRAY[1,2,3]);          -- 使用循环累加
EXPLAIN ANALYZE SELECT parallel_sum(ARRAY[1,2,3,4,5]);  -- 触发并行计算
  1. 内存管理优化
-- 流式处理重载
CREATE OR REPLACE FUNCTION stream_process(
  data JSONB,
  batch_size INT DEFAULT 1000
) RETURNS VOID AS $$
DECLARE
  batch JSONB[];
BEGIN
  FOR batch IN SELECT jsonb_array_elements(data) AS elem
               LIMIT batch_size
  LOOP
    INSERT INTO processed_data VALUES (batch->>'id');
  END LOOP;
END;
$$ LANGUAGE plpgsql;

-- 批量处理重载
CREATE OR REPLACE FUNCTION stream_process(
  data JSONB
) RETURNS VOID AS $$
BEGIN
  INSERT INTO processed_data 
  SELECT (elem->>'id')::INT 
  FROM jsonb_array_elements(data) AS elem;
END;
$$ LANGUAGE plpgsql;

总结

GaussDB函数重载技术为数据库开发带来三大核心价值:

​​接口统一化​​:通过多态性简化调用方式
​​逻辑精细化​​:实现参数级差异化处理
​​架构清晰化​​:保持业务逻辑集中管理
​​

posted @ 2025-05-26 16:23  喜酱喜酱  阅读(3)  评论(0)    收藏  举报