SQl存储过程-基于SQLSERVER讲解

目录

 Setp1:基础背景了解

1.1-什么是存储过程(What)?

1.2-存储过程的优缺点(Why)

优点

缺点

Setp2:基本语法学习

2.1-变量(看代码和注释)

2.2-流程控制

2.2.1-IF判断

2.2.2-While的使用(计算1-100的和)

2.2.3-Case 多重选择的使用

Setp3-自定义存储过程(HOW)

3.1-创建存储过程(带参数)

3.2-使用存储过程

3.3-重命名存储过程 

3.4-删除存储过程

Setp4-事务篇

4.1-事务的概述

 4.2-事务的特征

 4.3-事务的语法

 4.4-存储过程中使用事务

4.4.1-测试表SQL代码

4.4.2-没有事务的情况下 

4.4.3-使用事务的案例


        工作了一段时间都还是很少用到存储过程,之前的项目根本没有去写存储过程,最近就用到了这个存储过程,最近的这个项目多数都是写的存储过程,这几天在学习,就写下了这篇文章!

 Setp1:基础背景了解

1.1-什么是存储过程(What)?

       存储过程(Stored Procedure)是在大型数据库系统中,一组为了完成特定功能的SQL 语句集,它存储在数据库中,一次编译后永久有效,用户通过指定存储过程的名字并给出参数(如果该存储过程带有参数)来执行它。存储过程是数据库中的一个重要对象。在数据量特别庞大的情况下利用存储过程能达到倍数的效率提升。

提示: 其中系统自带有一些存储过程,存储过程用户也是可以自定义的,比如下面这句就是系统自带的存储过程

exec sp_tables; --查看表

1.2-存储过程的优缺点(Why)

优点

1.效率高:存储过程编译一次后,就会存到数据库,每次调用时都直接执行。一般的SQL语句每执行一次就需要编译一次,所以使用存储过程提高了效率。

2.降低网络流量:存储过程编译好会放在数据库,我们在远程调用时,不会传输大量的字符串类型的SQL语句。

3.复用性高:存储过程往往是针对一个特定的功能编写的,当再需要完成这个特定的功能时,可以再次调用该存储过程。

4.可维护性高:当功能要求发生小的变化时,修改之前的存储过程比较容易,花费精力少。


缺点

1.存储过程难以调试:虽然有些DB提供了调试功能,但是一般的账号根本就没有那种权限,更何况线上的数据库不可能会给你调试权限的,再进一步就算能调试效果也比程序的调试效果要差很多。

2.可移植性差:当碰到切换数据种类的时候,存储过程基本就会出现白写。

3.灵活性差:业务数据模型变动,存储过程必须跟着业务代码一起更改,如果是大型项目,这种改动是空前的,是要命的。

Setp2:基本语法学习

2.1-变量(看代码和注释

DECLARE @age int = 16; --Declare @Local_Var data_type,这里初始设置了age为16;
PRINT @age; -- 打印16
SET @age = 18; -- 为age变量设置值为18
PRINT @age; -- 打印18
> 16
> 18
> OK
> 查询时间: 0s

注意事项1:(SET只能为单个赋值,SELECT可以为多个赋值

DECLARE @age int,@name VARCHAR(20); 
SELECT @age= 18,@name = 'Jack'; 
PRINT N'年龄:' + CAST(@age AS VARCHAR) + '  姓名:' + @name;
> 年龄:18  姓名:Jack
> OK
> 查询时间: 0s


注意事项2:(看SQL后面的注释

DECLARE @name1 VARCHAR(20) = 'TOM';
SET @name1 = (SELECT Name FROM dbo.student WHERE ID = 2);
PRINT '-------------'
PRINT 'SET:'+ @name1;  --SET查询为空的时候,不会取上次的值,直接赋值为NULL
DECLARE @name VARCHAR(20) = 'TOM';
SELECT @name = Name FROM dbo.student WHERE ID = 2;
PRINT 'SELECT:'+@name; --SELECT查询为空的时候,赋值也为上次的给的值
> -------------
>  
> SELECT:TOM
> OK
> 查询时间: 0.001s

提示:当SELECT 和SET都有初始值的时候,但是赋值的时候SET为空就会为空,然而SELECT不会,它会取上一次的值

2.2-流程控制

2.2.1-IF判断

DECLARE @age INT = 18;

IF @age < 18
  BEGIN
		PRINT '你未成年!';
	END
ELSE IF @age = 18 
	BEGIN
		PRINT '刚好成年,适当上网哟!';
	END
ELSE 
	BEGIN
		PRINT '你已经成年,可以进入!';
	END
> 刚好成年,适当上网哟!
> OK
> 查询时间: 0s

2.2.2-While的使用(计算1-100的和)

DECLARE @i INT = 0,@NumSun INT = 0;
WHILE @i<=100  --开始循环
BEGIN
	SET @NumSun=@NumSun+@i;
	SET @i=@i+1;  --自增一
END 
print '结果是:' +CAST(@NumSun AS VARCHAR);
> 结果是:5050
> OK
> 查询时间: 0s

2.2.3-Case 多重选择的使用

DECLARE @sex INT,@RSex VARCHAR(10)
SET @sex= 1;
SELECT @RSex=
	CASE 
		WHEN @sex=1 THEN '男'
	ELSE '女'
END
PRINT '性别:' + @RSex;
> 性别:男
> OK
> 查询时间: 0s

Setp3-自定义存储过程(HOW

3.1-创建存储过程(带参数

定义存储过程的语法

CREATE  PROC[EDURE]  存储过程名

    @参数1  数据类型 = 默认值,

    …… ,

    @参数n  数据类型 OUTPUT

AS

SQL语句 -- 多个SQL用BEGIN END

BEGIN
    SQL语句 --就是这样用BEGIN END包裹起来
END

 

综合例子:(这里是为了演示运算和IF的使用所以我没有设置Id自增)

ALTER PROC up_addOrEditUser(
	@Id INT,  --定义变量为数字
	@Name VARCHAR(20), --定义变量为字符串
	@ResultId INT OUTPUT, --定义返回值在变量后面加上OUTPUT
	@ResultMsg VARCHAR(20) OUTPUT --定义返回值
)
AS
IF @Id < 0 OR @Id = 0 --判断
	 BEGIN
	  SET @Id = (SELECT MAX(ID) FROM dbo.student); -- 赋值
      IF(@Id IS NULL OR @Id = 0)
       BEGIN
         SET @Id = 1;
       END
      ELSE
         BEGIN
         SET @Id = @Id + 1;
        END
	  INSERT INTO dbo.student(ID,Name) VALUES(@Id,@Name); -- SQL语句
	  SELECT * FROM dbo.student WITH(nolock);
		SET @ResultMsg = '该操作是插入'; --赋值
	 END
ELSE
	BEGIN
	 UPDATE dbo.student SET Name = @Name WHERE ID = @Id;
     SET @ResultId = @@rowcount; --更新操作返回影响行数
	 SET @ResultMsg = '该操作是更新';
END

提示:其中的OUTPUT代表返回值 ,也可用retrun来返回,但是只能返回数字类型

3.2-使用存储过程

DECLARE @RId INT;
DECLARE @Rmsg VARCHAR(20);
EXEC up_addOrEditUser 1,'BertXie',@RId OUTPUT,@Rmsg OUTPUT;
PRINT '返回ID:' + CAST(@RId AS VARCHAR) + '操作是:' + @Rmsg;
> 返回ID:1
> OK
> 查询时间: 0.002s

3.3-重命名存储过程 

sp_rename oldName,newName;

3.4-删除存储过程

DROP PROCEDURE xxx;

Setp4-事务篇

4.1-事务的概述

       事务把所有的命令作为一个整体一起向系统提交或撤销操作请求,即这一组数据库命令要么同时成功要么同时失败

通俗小讲解:简单来说明我们现在下单买一个手机,假如钱已经付了,但是商品模块出现了问题,没有订单详情和已支付详情,但是我们没有用事务机制,导致我们的钱被扣了,但是没有证明我们买到商品的条件,这个就是没有用事务造成的。

 4.2-事务的特征

1.原子性(Atomicity):事务是数据库的逻辑工作单位,事务中包括的诸操作要么都做,要么都不做。

2.一致性(Consistency):事物完成时,数据必须是一致的,也就是说,和事物开始之前,数据存储中的数据处于一致状态。保证数据的无损

3.隔离性(Isolation):一个事务的执行不能被其他事务干扰。并发执行的各个事务之间不能互相干扰。

4.持续性(Durability):指一个事务一旦提交,它对数据库中数据的改变时永久性的。

 4.3-事务的语法

-- 开启事务
start transaction; -- 或者 begin;

-- 提交事务
commit;

-- 回滚事务
rollback;

语法解释:事务以begin transaction开始的,以commit或rollback 结束commit表示提交,既提交事务的所有操作。具体的说就是将事务中所有对数据库的更新写到磁盘上的物理数据中去,事务正常结束。Rollback表示回滚,在事务运行的过程中发生了异常操作,事务不能继续执行,系统将事务中对数据库的所有已完成的操作全部取消回滚到事务开始时的状态

 4.4-存储过程中使用事务

4.4.1-测试表SQL代码

CREATE TABLE [dbo].[Student] (
  [Id] bigint  IDENTITY(1,1) NOT NULL,
  [StudentName] varchar(16) COLLATE Chinese_PRC_CI_AS  NOT NULL,
  [Score] decimal(18,1)  NULL,
  [Subject] varchar(16) COLLATE Chinese_PRC_CI_AS  NULL
)
GO
INSERT INTO Student VALUES('BertXie',99.5,'数学');

提示:这里的StudentName加了一个唯一约束,等会方便测试

4.4.2-没有事务的情况下 

ALTER PROC upTransactionCase
AS
  BEGIN
	INSERT INTO Student VALUES('BertXie',100,'数学');
	INSERT INTO Student VALUES('Jack',100,'数学');
  END

--Msg 2627, Level 14, State 1, Server DESKTOP-BV542KL, Procedure upTransactionCase, Line 4
违反了 UNIQUE KEY 约束“snameKey”。不能在对象“dbo.Student”中插入重复键。重复键值为 (BertXie)。
语句已终止。

Procedure execution failed

[23000] [Microsoft][ODBC Driver 17 for SQL Server][SQL Server]违反了 UNIQUE KEY 约束“snameKey”。不能在对象“dbo.Student”中插入重复键。重复键值为 (BertXie)。 (2627)
[01000] [Microsoft][ODBC Driver 17 for SQL Server][SQL Server]语句已终止。 (3621)


时间: 0.002s

上面已经发生了异常但是并没有取消后面的操作,后面的Jack数据还是插入成功了

4.4.3-使用事务的案例

ALTER PROC upTransactionCase  
AS
BEGIN
  Set NOCOUNT ON; 
  Set XACT_ABORT ON;
  BEGIN TRY --开始捕捉异常
  BEGIN TRAN --开始事务
    INSERT INTO Student VALUES('BertXie',100,'数学');
	  INSERT INTO Student VALUES('Tom',100,'数学');
  COMMIT TRAN --提交事务
  END TRY --结束捕捉异常
  BEGIN CATCH --有异常被捕获
	 --在此可以使用xact_state()来判断是否有不可提交的事务,不可提交的事务
     --表示在事务内部发生错误了。Xact_state()有三种值:-1.事务不可提交;
     --1.事务可提交;0.表示没有事务,此时commit或者rollback会报错。
	 IF xact_state()= -1
       BEGIN
        ROLLBACK TRAN; --回滚事务
	   END	
  END CATCH --结束异常处理
END
显然Tom没有插入成功,一个失败了都失败了

  • 18
    点赞
  • 105
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值