函数、存储过程和聚集(聚合)函数

一、基本概念

1. 函数 (Function)

定义: 完成特定功能、有返回值的数据库对象
特点:

必须有返回值 (单个值或表)

可以在 SQL 语句中直接调用

通常用于计算和转换数据

不能有副作用(不能修改数据库状态)

sql 复制代码
-- 示例:标量函数(返回单个值)
CREATE FUNCTION dbo.GetEmployeeName(@EmpID INT)
RETURNS VARCHAR(100)
AS
BEGIN
    DECLARE @Name VARCHAR(100);
    SELECT @Name = Name FROM Employees WHERE EmpID = @EmpID;
    RETURN @Name;
END;

-- 使用
SELECT dbo.GetEmployeeName(1001);

-- 示例:表值函数(返回表)
CREATE FUNCTION dbo.GetEmployeesByDept(@DeptID INT)
RETURNS TABLE
AS
RETURN (
    SELECT * FROM Employees WHERE DeptID = @DeptID
);

2. 存储过程 (Stored Procedure)

定义:预编译的 SQL 代码块 ,可包含复杂的业务逻辑
特点:

可以没有返回值 ,也可以有多个返回值 (通过 OUTPUT 参数)

不能在 SQL 语句中直接调用(使用 EXEC 执行)

可以修改数据库状态 (INSERT、UPDATE、DELETE)

支持复杂的事务处理和错误处理

性能更好(预编译)

sql 复制代码
-- 示例:存储过程
CREATE PROCEDURE sp_UpdateEmployeeSalary
    @EmpID INT,
    @IncreasePercent DECIMAL(5,2),
    @NewSalary DECIMAL(10,2) OUTPUT
AS
BEGIN
    BEGIN TRANSACTION;
    TRY
        UPDATE Employees 
        SET Salary = Salary * (1 + @IncreasePercent/100)
        WHERE EmpID = @EmpID;
        
        SELECT @NewSalary = Salary FROM Employees WHERE EmpID = @EmpID;
        
        COMMIT TRANSACTION;
    END TRY
    BEGIN CATCH
        ROLLBACK TRANSACTION;
        THROW;
    END CATCH;
END;

-- 使用
DECLARE @NewSal DECIMAL(10,2);
EXEC sp_UpdateEmployeeSalary 1001, 10, @NewSal OUTPUT;

3. 聚集/聚合函数 (Aggregate Function)

定义 :对一组值进行计算返回单个值 的函数
特点

内置函数 (SUM、AVG、COUNT、MAX、MIN 等)

通常与 GROUP BY 一起使用

多行数据进行聚合计算

返回单个汇总值

sql 复制代码
-- 示例:聚合函数
SELECT 
    DeptID,
    COUNT(*) AS EmployeeCount,      -- 计数
    AVG(Salary) AS AvgSalary,       -- 平均
    SUM(Salary) AS TotalSalary,     -- 求和
    MAX(Salary) AS MaxSalary,       -- 最大
    MIN(Salary) AS MinSalary        -- 最小
FROM Employees
GROUP BY DeptID;

二、主要区别

三、联系与共同点

1. 都是数据库对象

都存储在数据库中

都可以重复使用

都能提高代码复用性

2. 都能封装逻辑

sql 复制代码
-- 函数封装计算逻辑
CREATE FUNCTION dbo.CalculateTax(@Amount DECIMAL)
RETURNS DECIMAL
AS BEGIN
    RETURN @Amount * 0.13;
END;

-- 存储过程封装业务流程
CREATE PROCEDURE sp_ProcessOrder
    @OrderID INT
AS
BEGIN
    -- 检查库存
    -- 更新订单状态
    -- 扣减库存
    -- 记录日志
END;

-- 聚合函数封装统计逻辑
SELECT AVG(Salary) FROM Employees; -- 封装了求平均的逻辑

3. 都可以带参数

sql 复制代码
-- 函数参数
SELECT dbo.GetEmployeeName(1001);

-- 存储过程参数
EXEC sp_UpdateSalary 1001, 10;

-- 聚合函数(隐式参数)
SELECT AVG(Salary) -- Salary 是隐式参数

4. 可以组合使用

sql 复制代码
-- 在存储过程中使用函数和聚合函数
CREATE PROCEDURE sp_DepartmentStats
    @DeptID INT
AS
BEGIN
    DECLARE @AvgSalary DECIMAL;
    
    -- 使用聚合函数
    SELECT @AvgSalary = AVG(Salary) 
    FROM Employees 
    WHERE DeptID = @DeptID;
    
    -- 使用自定义函数
    SELECT 
        EmpID,
        Name,
        dbo.CalculateTax(Salary) AS Tax
    FROM Employees
    WHERE DeptID = @DeptID;
END;

四、使用场景建议

✅ 使用函数的场景
需要在查询中计算或转换数据
需要返回单个值或表
逻辑相对简单,无副作用
✅ 使用存储过程的场景
复杂的业务流程
需要事务控制
需要批量处理数据
需要错误处理
多个相关操作需要一起执行
✅ 使用聚合函数的场景
统计分析
报表生成
数据汇总
GROUP BY 分组计算

五、实际例子对比

sql 复制代码
-- 1. 函数:计算员工年龄
CREATE FUNCTION dbo.CalculateAge(@BirthDate DATE)
RETURNS INT
AS
BEGIN
    RETURN DATEDIFF(YEAR, @BirthDate, GETDATE());
END;

-- 2. 存储过程:处理员工晋升
CREATE PROCEDURE sp_PromoteEmployee
    @EmpID INT,
    @NewPosition VARCHAR(50)
AS
BEGIN
    BEGIN TRANSACTION;
    
    UPDATE Employees 
    SET Position = @NewPosition,
        Salary = Salary * 1.2,
        PromoteDate = GETDATE()
    WHERE EmpID = @EmpID;
    
    INSERT INTO PromotionHistory (EmpID, NewPosition, PromoteDate)
    VALUES (@EmpID, @NewPosition, GETDATE());
    
    COMMIT TRANSACTION;
END;

-- 3. 聚合函数:统计部门信息
SELECT 
    d.DeptName,
    COUNT(e.EmpID) AS EmpCount,           -- 聚合:计数
    AVG(dbo.CalculateAge(e.BirthDate)) AS AvgAge,  -- 聚合 + 函数
    SUM(e.Salary) AS TotalBudget          -- 聚合:求和
FROM Departments d
LEFT JOIN Employees e ON d.DeptID = e.DeptID
GROUP BY d.DeptName;
相关推荐
cspttty1 分钟前
FP&A应届岗技能路线:Excel建模、SQL取数、BI看板与预算分析
大数据·数据库
微学AI20 分钟前
飞牛 NAS 部署 prompts.chat:自建提示词库、导入社区内容,再配置固定公网访问
数据库·内网穿透
羑悻的小杀马特22 分钟前
从写 YAML 到集群自愈:KES-Operator 把 KES 集群接进 Kubernetes 原生体系
运维·数据库·容器·kubernetes
隔窗听雨眠24 分钟前
Oracle普通表自动改造分区表:从评估到自动化维护的完整实战指南
oracle
bksczm26 分钟前
MySQL基础篇之事务
linux·数据库·sql·mysql
李白客27 分钟前
数据库管理工具怎么选?Navicat、DataGrip、DBeaver 六维横向对比与选型建议
运维·数据库
马立杰28 分钟前
mysql中Illegal mix of collations for operation “UNION”错误的解决方法
数据库·sql·网络安全
蓝速科技30 分钟前
蓝速 K10 三防平板在工业恶劣工况下的选型与应用指南
大数据·运维·数据库·人工智能·科技
bksczm32 分钟前
MySQL基础篇之视图与用户管理
linux·数据库·sql·mysql
香菜TTT38 分钟前
怎么实现MySQL的主从同步机制
数据库·mysql