当前位置:首页 > 问答 > 正文

教你怎么用SQL里的参数变量,简单传递那些记录值,操作起来其实没那么复杂

很多人刚开始学SQL,看到存储过程或者动态SQL里用到的参数变量,会觉得头大,感觉这又是程序员才搞得定的高级玩意儿,其实不然,SQL里的参数变量就是个“临时储物箱”,你先把一个值放进去,然后带着这个箱子去执行SQL命令,命令会从箱子里取东西用,这么一想,是不是就简单多了?它的核心目的就是为了让一条SQL语句不用写死,可以灵活地重复使用。

最基本的一招:声明和赋值

想象一下,你要从一个叫“员工表”里找出所有属于“销售部”的员工,通常你会写:SELECT * FROM 员工表 WHERE 部门 = ‘销售部’;,但如果明天你想查“技术部”的呢?就得把SQL语句改一下,用上变量,就不用每次都改语句了。

怎么用?分三步走,特别直白:

  1. 声明变量:就是告诉数据库:“喂,我准备用一个小盒子了,名字叫@部门名,里面准备放字符串类型的数据,最多放10个字符。” 在SQL Server里,这么写:DECLARE @部门名 VARCHAR(10); 这就相当于你向系统申请了一个贴著“@部门名”标签的空盒子。
  2. 给变量赋值:就是把具体的值放进盒子里,有两种常见方式,第一种是直接塞进去:SET @部门名 = ‘销售部’;,第二种是从表格里查出一个值塞进去,SELECT @部门名 = 部门名称 FROM 部门表 WHERE 部门ID = 1;,这样,变量@部门名里装的就是部门ID为1的那个部门的名字了。
  3. 使用变量:你就可以在SQL语句里直接使用这个贴著标签的盒子了,你的查询语句就变成了:SELECT * FROM 员工表 WHERE 部门 = @部门名;,下次你想查技术部,只需要在执行查询前,把赋值那句改成SET @部门名 = ‘技术部’; 就行了,后面的查询语句完全不用动。

这个简单的三步法,是理解所有参数变量用法的基础,根据参考资料的说明,这种用法在需要频繁更换查询条件值时尤其方便。

进阶玩法:在存储过程中当参数用

刚才那是你自己在同一个脚本里声明和赋值,更强大的用法是把变量变成存储过程的“入口”,存储过程可以理解为一段预先写好的、有名字的SQL程序,你可以给它设计几个“入口”,也就是参数。

我们创建一个存储过程,叫“查询某部门员工”:CREATE PROCEDURE 查询员工 @传入部门名 VARCHAR(10),这里的@传入部门名就是这个存储过程的参数,它像个空箱子放在门口。

当你调用这个存储过程时,才把具体的值递进去:EXEC 查询员工 @传入部门名 = ‘销售部’;,或者更简单:EXEC 查询员工 ‘销售部’;

这样做的好处是什么?是你的应用程序(比如一个网站的后台程序)可以非常轻松地调用这个存储过程,程序里可能有一个下拉框让用户选择部门,用户选了“财务部”,程序就直接执行 EXEC 查询员工 ‘财务部’;,SQL代码和程序代码完全分离,管理起来清晰,也安全。

更灵活但也更需小心的玩法:动态SQL

你的需求会更复杂,你不光想动态传递部门名称,还想动态决定按什么字段排序(是按工号还是按入职日期?),这时候,普通的变量就有点力不从心了,因为像字段名、表名这类数据库对象的名字,是不能直接用变量替代的。

怎么办呢?这就需要“动态SQL”出场了,它的思路是:你不是不能直接拼吗?那我先把整句SQL命令当成一个字符串拼装好,把这个字符串赋给一个变量,然后再执行这个字符串变量。

举个例子:

DECLARE @排序字段 NVARCHAR(20) = ‘入职日期’;
DECLARE @SQL语句 NVARCHAR(MAX);
SET @SQL语句 = ‘SELECT * FROM 员工表 ORDER BY ‘ + @排序字段;
EXEC sp_executesql @SQL语句;

你看,这里我们先拼出了一个完整的字符串 ‘SELECT * FROM 员工表 ORDER BY 入职日期’,然后执行它,如果你想按“姓名”排序,只需要改变量@排序字段的值就行了。

这里有个非常重要的警告! 参考资料来源中都重点强调了一个问题:SQL注入攻击,如果你拼接的变量内容来自用户的直接输入(比如一个搜索框),而你没有做任何安全检查,那么黑客就可以输入一些恶意的字符串,让你的SQL语句变成他想要的样子,比如删掉你的数据表,这非常危险。

在动态SQL中,如果参数是用户输入的数据值(比如搜索关键词),绝不能直接拼接,应该使用参数化查询,也就是sp_executesql的另一种形式,它允许你将参数单独传递,数据库会严格区分“命令”和“数据”,从而免疫这类攻击。

DECLARE @部门名 NVARCHAR(10) = ‘销售部’;
DECLARE @SQL语句 NVARCHAR(MAX);
SET @SQL语句 = ‘SELECT * FROM 员工表 WHERE 部门 = @传入部门名’;
EXEC sp_executesql @SQL语句, N’@传入部门名 NVARCHAR(10)’, @传入部门名 = @部门名;

虽然看起来复杂了点,但这是保证数据库安全的关键做法。

总结一下

SQL里的参数变量一点也不神秘,你把它当成一个传递信息的信使或者一个临时储物箱就行。

  • 简单使用:就是DECLARE(声明)、SET(赋值)、然后直接在SQL里用。
  • 在存储过程里:让存储过程更通用,成为可重复调用的模块。
  • 动态SQL:处理更灵活的需求,但务必警惕SQL注入,对用户输入的值要使用参数化查询来传递。

多动手试几次,从最简单的声明赋值开始,你会很快发现,用上变量之后,你的SQL能力就上了一个新台阶,写出的脚本又灵活又强大。

教你怎么用SQL里的参数变量,简单传递那些记录值,操作起来其实没那么复杂