GaussDB数据库SQL系列:函数重载技术深度解析
GaussDB数据库SQL系列:函数重载技术深度解析
一、函数重载的核心价值
1.1 多态性实现
参数差异化处理:同一函数名适配不同参数类型(如整数/字符串处理)
接口统一化:提供一致的调用方式(如calculate()同时处理金额和数量)
代码复用增强:避免创建多个功能相似的函数(如不同数据类型的校验逻辑)
1.2 典型应用场景
场景 实现方式 业务价值
数值类型适配 重载处理INT/DECIMAL/BIGINT 统一数值计算接口
数据格式转换 重载处理JSON/TEXT/CSV输入 简化异构数据接入
动态参数控制 重载不同参数数量的版本 灵活应对业务规则变化
二、重载函数定义语法
- 参数数量重载
-- 整数版本
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
- 参数类型重载
-- 数值计算版本
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
- 参数顺序重载
-- 先时间后金额版本
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()); -- 参数顺序(金额,时间)
三、高级应用技巧
- 结合类型转换的重载
-- 自动类型推断版本
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'); -- 强制转为字符串
- 递归重载实现树形结构
-- 基础节点处理版本
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); -- 只显示第三层以下节点
四、性能优化策略
- 执行计划差异化
-- 创建带统计信息的重载函数
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]); -- 触发并行计算
- 内存管理优化
-- 流式处理重载
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函数重载技术为数据库开发带来三大核心价值:
接口统一化:通过多态性简化调用方式
逻辑精细化:实现参数级差异化处理
架构清晰化:保持业务逻辑集中管理