存储过程跟SQL语句比较,各有什么优缺点?
存储过程有以下优点
- 由于应用程序随着时间推移会不断更改,增删功能,SQL过程代码会变得更复杂,存储过程为封装此代码提供了一个替换位置。
- 存储过程可以用于降低网络流量,存储过程代码直接存储于数据库中,所以不会产生大量SQL语句的代码流量。
- 使用存储过程使您能够増强对执行计划的重复使用,由此可以通过使用远程过程调用(RPC)处理服务器上的存储过程面提高性能。RPC封装参数和调用服务器端过程的方式使引擎能够轻松地找到匹配的执行计划,并只需插入更新的参数值。
- 可维护性高,更新存储过程通常比更改、测试以及重新部署程序集需要较少的时间和精力。
- 代码精简一致,一个存储过程可以用于应用程序代码的不同位置。
- 增强安全性,如通过向用户授予对存储过程(而不是基于表)的访问权限,它们可以提供对特定数据的访问,在一定程度上可以提高代码安全,防止SQL注入。Sqlparameter类指定存储过程参数的数据类型,作为深层次防御性策略的一部分,可以验证用户提供的值类型。
存储过程的缺点有以下两点
- 如果更改范围大到需要对输入存储过程的参数进行更改,或者要更改由其返回的数据,则仍需要更新程序集中的代码以添加参数、更新GetValue()调用等,这时候估计比较烦琐了。
- 可移植性差,由于存储过程将应用程序绑定到SQL Server,因此使用存储过程封装业务逻辑将限制应用程序的可移植性。如果应用程序的可移植性在用户的环境中非常重要,则将业务逻辑封装在不特定于RDBMS的中间层中可能是一个更佳的选择。
分析
- 这道题目考查面试者对存储过程的理解是否深刻,在众多公司的面试中非常常见。
- 那么什么是存储过程呢?
- 简单地说,存储过程即将常用的或很复杂的工作,预先用SQL语句写好并用一个指定的名称存储起来,则以后需要数据库提供与已定义好的存储过程功能相同的服务时,只需调用
execute
即可自动完成命令。 - 相对于在程序中动态编写SQL语句,存储过程更为方便,编程者只需要专注于程序的业务逻辑,数据库相关的操作可通过调用预先编写好的存储过程实现。
写一条SQL语句筛选出每门课程的前两名
在SQL Server数据库中,有一个数据表
grade(学生成绩)
,它有3个字段:
字段名 类型 说明 sid int 主键,学生编号 cid int 课程编号 ac int 成绩 写一条SQL语句,筛选出每门课程的前两名的学生编号、课程编号、成绩并列序。
解答
select a.sid, a.cid, a.ac from grade as a
where a.sid in
(select top 2 sid from grade where cid=a.cid order by ac desc)
分析
- 本题字面上略显复杂,实际可简化为对于每门课程,筛选出成绩前两名的学生并按成绩排序,将这几组(数量取决于课程种类)前两名的学生记录的所有字段列出来。
- 解答时为了书写更简洁,用a作为
grade
表的别名,指派表的别名时,可以使用也可以不便用AS关键字。 - 如果为表指派了别名,那么在该T-SQL语句中对该表的所有显式引用都必须使用别名,而不能使用表名。
这里再次使用了IN子句,以获取每门课程已排序过的前两名记录的sid字段。 - 说明:
order by ac desc
代表按ac字段(即成绩)排序,并以降序顺序排列。
查询表A中存在username字段值重复3次以上的字段。
解答
select username from
(select count(username) as num, username from A group by username) as t
where num < 3
分析
- 本题门考查了
GROUP BY
子句及聚合函数count
的应用。 - 在如以下代码所示的语句中,通过
GROUP BY
按username
字段分组,获得了表t,其中每条记录有num
字段和username
字段。
(select count(username) as num, username from A group by username) as t
- 说明num字段为执行分组时,通过
count
函数将username
字段相同的记录数计算的值,获得表t后,再次査询其username 字段值,记录必须符合num字段值大于3的条件。 - 这样,name字段值重复3次以l的记录就被筛选出来了。