存储过程懂不懂

存储过程的官方定义是这么说的:

存储过程(Stored Procedure)是一组为了完成特定功能的SQL语句集,经编译后存储在数据库中。用户通过指定存储过程的名字并给出参数(如果该存储过程带有参数)来执行它。存储过程是数据库中的一个重要对象,任何一个设计良好的数据库应用程序都应该用到存储过程。


其实说的再简单一点,她就是一个过程而已,对!就是和你所熟知的那个Sub……End Sub实质上是一个东西。

存储过程除了与一般的过程拥有同样的优点外(多次调用,可移植性好等),还在一定程度上减少了网络流量(只需要传送调用过程的语句);而且通过对执行存储过程的权限控制还能保证系统数据的安全等等,等等。

简而言之,使用存储过程存在很多好处,但是却没有明显的坏处。

OK!铺垫完毕,开始正式介绍——存储过程。(这里应该有掌声)

l 基本语法格式

n 创建存储过程

   1: create proc 过程名/*建立存储过程*/
<!--CRLF-->
   2: @parameter 参数类型  /*输入参数*/
<!--CRLF-->
   3: ...
<!--CRLF-->
   4: @parameter 参数类型  output/*输出参数*/
<!--CRLF-->
   5: ...
<!--CRLF-->
   6: as
<!--CRLF-->
   7: begin
<!--CRLF-->
   8:     命令行或命令块/*需要存储过程执行的操作*/
<!--CRLF-->
   9: end
<!--CRLF-->

n 执行存储过程

   1: execute 过程名 [参数,参数……][output] 
<!--CRLF-->

n 修改存储过程

   1: alter proc 过程名*/修改存储过程*/
<!--CRLF-->
   2: @parameter 参数类型  /*输入参数*/
<!--CRLF-->
   3: ...
<!--CRLF-->
   4: @parameter 参数类型  ouput/*输出参数*/
<!--CRLF-->
   5: ...
<!--CRLF-->
   6: as
<!--CRLF-->
   7: begin
<!--CRLF-->
   8:    命令行货命令块/*存储过程执行的操作*/
<!--CRLF-->
   9: End
<!--CRLF-->

n 重命名存储过程

   1: sp_rename 原过程名,新过程名
<!--CRLF-->

n 删除存储过程

   1: drop proc存储过程名,[存储过程名2,……]
<!--CRLF-->

l 存储过程在哪里?

无论是系统自带的存储过程(在数据库master中,以sp_开头)还是自定义的存储过程,都在相应数据库中的“可编译性”——“存储过程”中,可以点击查看。

PS:修改、重命名、删除存储过程也可以在相应数据库中的“可编译性”——“存储过程”中右键进行相应相关操作(看个人喜好)。

l 实战演练

1. 建立数据库(略)

文章末尾附数据对应脚本,执行即可。image

2. 建立无参数存储过程

   1: create proc proc1
<!--CRLF-->
   2: as 
<!--CRLF-->
   3: begin
<!--CRLF-->
   4:    select a.StuNo,StuName,StuCollege,StuScore from Student a
<!--CRLF-->
   5:    where StuScore >90
<!--CRLF-->
   6: end
<!--CRLF-->

3. 建立有参数存储过程

   1: CREATE proc proc2
<!--CRLF-->
   2: @coures varchar(20)
<!--CRLF-->
   3: as 
<!--CRLF-->
   4: begin
<!--CRLF-->
   5:    select StuNo,StuName,StuCollege,StuScore from Student a
<!--CRLF-->
   6:    where StuScore=@Coures
<!--CRLF-->
   7: end
<!--CRLF-->

4. 执行存储过程

   1: execute proc1
<!--CRLF-->
   2: execute proc2 '80'
<!--CRLF-->

如图所示image

附:对应数据脚本

   1: USE [StuInfo]
<!--CRLF-->
   2: GO
<!--CRLF-->
   3: SET ANSI_NULLS ON
<!--CRLF-->
   4: GO
<!--CRLF-->
   5: SET QUOTED_IDENTIFIER ON
<!--CRLF-->
   6: GO
<!--CRLF-->
   7: SET ANSI_PADDING ON
<!--CRLF-->
   8: GO
<!--CRLF-->
   9: CREATE TABLE [dbo].[Student](
<!--CRLF-->
  10:        [StuNo] [varchar](50) NULL,
<!--CRLF-->
  11:        [StuName] [varchar](50) NULL,
<!--CRLF-->
  12:        [StuCollege] [varchar](50) NULL,
<!--CRLF-->
  13:        [StuScore] [varchar](50) NULL
<!--CRLF-->
  14: ) ON [PRIMARY]
<!--CRLF-->
  15: GO
<!--CRLF-->
  16: SET ANSI_PADDING OFF
<!--CRLF-->
  17: GO
<!--CRLF-->
  18: INSERT [dbo].[Student] ([StuNo], [StuName], [StuCollege], [StuScore]) VALUES (N'1', N'丁福东', N'物电学院', N'80')
<!--CRLF-->
  19: INSERT [dbo].[Student] ([StuNo], [StuName], [StuCollege], [StuScore]) VALUES (N'2', N'斯蒂芬', N'物电学院', N'75')
<!--CRLF-->
  20: INSERT [dbo].[Student] ([StuNo], [StuName], [StuCollege], [StuScore]) VALUES (N'3', N'梵蒂冈', N'数信学院', N'98')
<!--CRLF-->
  21: INSERT [dbo].[Student] ([StuNo], [StuName], [StuCollege], [StuScore]) VALUES (N'4', N'金凯华', N'国贸学院', N'69')
<!--CRLF-->
  22: INSERT [dbo].[Student] ([StuNo], [StuName], [StuCollege], [StuScore]) VALUES (N'5', N'安淑霞', N'数信学院', N'78')
<!--CRLF-->
  23: INSERT [dbo].[Student] ([StuNo], [StuName], [StuCollege], [StuScore]) VALUES (N'6', N'张成栋', N'生科学院', N'84')
<!--CRLF-->
  24: INSERT [dbo].[Student] ([StuNo], [StuName], [StuCollege], [StuScore]) VALUES (N'7', N'安世伟', N'国贸学院', N'95')
<!--CRLF-->
  25: INSERT [dbo].[Student] ([StuNo], [StuName], [StuCollege], [StuScore]) VALUES (N'8', N'任文才', N'生科学院', N'71')
<!--CRLF-->
  26: INSERT [dbo].[Student] ([StuNo], [StuName], [StuCollege], [StuScore]) VALUES (N'9', N'秦福德', N'物电学院', N'54')
<!--CRLF-->
  27: INSERT [dbo].[Student] ([StuNo], [StuName], [StuCollege], [StuScore]) VALUES (N'10', N'孙德荣', N'生科学院', N'68')
<!--CRLF-->
存储过程和存储函数都是数据库中用来封装一系列 SQL 操作的程序单元,它们都保存在数据库服务器上,可以被反复调用。虽然它们看起来很像,但有几个关键的区别,尤其体现在**用途、返回值和使用方式**上。 我们可以用一个生活中的比喻来帮助理解: --- ### 🍳 比喻:厨房里的“厨师” 想象你有一个智能厨房,里面有两位助手: - **存储过程**:像一个全能厨师,你可以让他做一整桌菜(执行一系列操作),但他不一定非得端出一道“主菜”给你。 - **存储函数**:像一个专门做蛋糕的师傅,你让他做一个蛋糕,他必须做出一个蛋糕并交给你(必须有返回值)。 --- ### ✅ 主要区别(通俗解释) | 对比项 | 存储过程(Stored Procedure) | 存储函数(Stored Function) | |--------|-------------------------------|------------------------------| | **能不能返回结果?** | 可以返回多个值(通过输出参数),也可以不返回 | **必须返回一个值**(就像数学函数 `f(x)`) | | **能不能在SQL语句中调用?** | ❌ 不能直接在 `SELECT` 中使用 | ✅ 可以直接在 `SELECT` 中使用,比如 `SELECT my_function(10);` | | **主要用途** | 执行复杂的业务逻辑,比如转账、生成报表、批量处理数据等 | 计算某个值,比如计算折扣价、年龄、格式化字符串等 | | **是否允许有输出参数?** | ✅ 支持输入、输出、输入输出参数 | ❌ 通常只支持输入参数 | | **能否调用另一个?** | ✅ 存储过程可以调用函数 | ✅ 函数不能调用存储过程(大多数数据库限制) | --- ### 💡 举个例子(MySQL) 假设我们有一个用户表: ```sql CREATE TABLE users ( id INT PRIMARY KEY, name VARCHAR(50), birth_year INT ); ``` #### ✅ 存储函数示例:计算年龄 ```sql DELIMITER $$ CREATE FUNCTION calculate_age(birth_year INT) RETURNS INT READS SQL DATA DETERMINISTIC BEGIN RETURN YEAR(CURDATE()) - birth_year; END$$ DELIMITER ; ``` 👉 使用方式(可以直接在查询中用): ```sql SELECT name, calculate_age(birth_year) AS age FROM users; ``` > ✔️ 这就像调用一个公式:`age = 当前年份 - 出生年份` --- #### ✅ 存储过程示例:给某人改名字并记录日志 ```sql DELIMITER $$ CREATE PROCEDURE update_user_name( IN user_id INT, IN new_name VARCHAR(50) ) BEGIN -- 更新名字 UPDATE users SET name = new_name WHERE id = user_id; -- 记录日志(假设有个日志表) INSERT INTO logs(message, created_at) VALUES (CONCAT('User ', user_id, ' renamed to ', new_name), NOW()); -- 可选:返回一条消息 SELECT CONCAT('Updated user ', user_id) AS result; END$$ DELIMITER ; ``` 👉 调用方式: ```sql CALL update_user_name(1, 'Alice'); ``` > ✔️ 它做了两件事:改名字 + 写日志,不需要返回具体值,而是完成任务。 --- ### 🔍 总结一句话: - 如果你想**做一件事或一连串动作**(如更新、插入、打印报告),用 **存储过程**。 - 如果你想**计算一个结果**(如价格、年龄、状态码),并在查询中使用它,用 **存储函数**。 --- ### ⚠️ 注意事项 - 不是所有数据库都完全一样(比如 Oracle 和 MySQL 稍有不同)。 - 函数更“干净”,适合嵌入表达式;过程更“强大”,适合复杂流程控制。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值