导读:本期聚焦于小伙伴创作的《如何编写动态SQL存储过程_使用sp_executesql执行灵活查询》,敬请观看详情,探索知识的价值。以下视频、文章将为您系统阐述其核心内容与价值。如果您觉得《如何编写动态SQL存储过程_使用sp_executesql执行灵活查询》有用,将其分享出去将是对创作者最好的鼓励。

动态SQL存储过程可以根据运行时传入的参数动态调整查询逻辑,适配多变的业务查询需求,在SQL Server中,使用sp_executesql执行动态SQL是更安全高效的选择,相比EXEC直接执行拼接字符串,它支持参数化,还能复用查询执行计划。

如何编写动态SQL存储过程_使用sp_executesql执行灵活查询

动态SQL存储过程的应用场景

当业务查询的条件不固定时,比如用户可以选择按姓名、年龄、部门等多个字段组合查询,固定条件的存储过程需要写大量IF判断,代码冗余且维护成本高,此时动态SQL就能发挥作用。常见的适用场景包括:

  • 多条件可选查询,用户可以选择部分条件进行筛选
  • 查询的表名、字段名需要根据参数动态指定
  • 排序规则、分页参数需要运行时动态调整

sp_executesql的基本用法

sp_executesql是SQL Server提供的系统存储过程,用于执行动态拼接的SQL语句,它的语法结构如下:

-- 基本语法
sp_executesql 
    @stmt = N'动态SQL语句',  -- 要执行的SQL字符串,需要加N前缀表示Unicode
    @params = N'参数定义',    -- 可选,定义动态SQL中用到的参数
    @参数名1 = 参数值1,       -- 给动态SQL中的参数赋值
    @参数名2 = 参数值2

需要注意,动态SQL语句和参数定义都需要用N前缀标记为Unicode字符串,否则可能出现中文乱码或者执行报错的问题。

编写动态SQL存储过程的完整示例

下面以员工表查询为例,编写一个支持可选条件查询的动态存储过程,员工表结构如下:

字段名类型说明
idint员工ID,主键
namenvarchar(50)员工姓名
ageint员工年龄
departmentnvarchar(50)所属部门

存储过程实现代码

这个存储过程支持传入姓名、年龄、部门三个可选参数,传入对应参数就按该条件筛选,不传入则忽略该条件:

CREATE PROCEDURE GetEmployeeByCondition
    @name nvarchar(50) = NULL,  -- 姓名筛选条件,默认NULL
    @age int = NULL,            -- 年龄筛选条件,默认NULL
    @department nvarchar(50) = NULL  -- 部门筛选条件,默认NULL
AS
BEGIN
    SET NOCOUNT ON;  -- 不返回受影响的行数,提升性能
    -- 定义动态SQL基础语句
    DECLARE @sql nvarchar(1000) = N'SELECT id, name, age, department FROM Employee WHERE 1=1';
    -- 定义参数列表,对应动态SQL中使用的参数
    DECLARE @param_def nvarchar(500) = N'@name nvarchar(50), @age int, @department nvarchar(50)';
    
    -- 根据传入参数动态拼接条件
    IF @name IS NOT NULL
        SET @sql = @sql + N' AND name LIKE @name';
    IF @age IS NOT NULL
        SET @sql = @sql + N' AND age = @age';
    IF @department IS NOT NULL
        SET @sql = @sql + N' AND department = @department';
    
    -- 执行动态SQL,传入参数
    EXEC sp_executesql 
        @stmt = @sql,
        @params = @param_def,
        @name = @name,
        @age = @age,
        @department = @department;
END
GO

存储过程调用示例

调用上述存储过程的不同场景示例:

-- 只按姓名查询,查询姓名包含张三的员工
EXEC GetEmployeeByCondition @name = N'%张三%';

-- 按部门和年龄查询,查询部门为技术部且年龄30岁的员工
EXEC GetEmployeeByCondition @department = N'技术部', @age = 30;

-- 不传入任何参数,查询所有员工
EXEC GetEmployeeByCondition;

使用sp_executesql的注意事项

  • 动态SQL中如果用到表名、字段名等对象名动态拼接,不能用参数化,只能直接拼接字符串,此时需要做好输入校验,避免SQL注入。比如要动态指定表名,需要先判断传入的表名是否在允许的列表中。
  • 参数定义中的参数类型和动态SQL中使用的参数类型要一致,否则会出现类型转换错误。
  • 动态SQL的执行权限需要单独授予,执行存储过程的用户不一定有执行动态SQL中语句的权限,需要确认权限配置正确。
  • 尽量把固定的查询逻辑放在动态SQL外部,只把需要变化的部分放在动态拼接中,减少动态SQL的长度,提升可维护性。

sp_executesql和EXEC直接执行的对比

很多开发者会直接使用EXEC执行拼接好的字符串,比如EXEC('SELECT * FROM Employee WHERE name = ''' + @name + ''''),这种方式存在明显弊端:

  • 容易引发SQL注入,如果传入的@name参数是'' OR 1=1 --,就会查询出所有数据
  • 每次执行都会生成新的执行计划,无法复用,性能较差
  • 字符串拼接复杂,尤其是包含引号的时候容易出错

而sp_executesql支持参数化,能有效避免上述问题,是执行动态SQL的推荐方式。

动态SQLsp_executesql存储过程SQL_Server修改时间:2026-07-15 08:18:29

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。