参考网址:https://www.cnblogs.com/chaoa/articles/3894311.html(存储过程)
https://www.cnblogs.com/selene/p/4480328.html(游标)
--创建学生表 create table student1( id int, cardId int, name varchar(32), birthday datetime, sex varchar(32) ) 1 1 王男 1996-08-27 09:00:00.000 男 2 2 杨幂 1995-04-20 06:00:00.000 女 3 3 程峰 1988-09-17 15:30:00.000 男 4 4 唐嫣 1895-05-27 14:30:28.000 女 5 5 王菲 1990-01-20 19:00:00.000 女 6 6 王忠磊 1980-08-08 08:09:00.000 男 --一、定义变量 参考:[https://www.cnblogs.com/chaoa/articles/3894311.html] --简单赋值 declare @a int set @a=5 print @a --SELECT @a --使用select语句赋值 declare @user1 nvarchar(50) select @user1='张三' print @user1 declare @user2 nvarchar(50) select @user2 = name from student1 where ID=1 print @user2 --使用update语句赋值 declare @user3 nvarchar(50) update student1 set @user3 = name where ID=1 --print @user3 SELECT @user3 --二、表、临时表、表变量 --创建临时表1 create table #DU_User1 ( id int, cardId int, name varchar(32), birthday datetime, sex varchar(32) ); --向临时表1插入一条记录 insert into #DU_User1 (id, cardId, name, birthday, sex) values (11,11,'刘亦菲',GETDATE(),'女'); --从student1查询数据,填充至新生成的临时表(在插入数据的同时创建了临时表) select * into #DU_User2 from student1 where ID<8 --查询并联合两临时表 select * from #DU_User2 where ID<3 union select * from #DU_User1 --删除两临时表 drop table #DU_User1 drop table #DU_User2 --创建临时表 CREATE TABLE #t( id int, cardId int, name varchar(32), birthday datetime, sex varchar(32) ) --将查询结果集(多条数据)插入临时表 insert into #t select * from student1 --不能这样插入 --select * into #t from student1 --添加一列,为int型自增长子段 alter table #t add [myid] int NOT NULL IDENTITY(1,1) --添加一列,默认填充全球唯一标识 alter table #t add [myid1] uniqueidentifier NOT NULL default(newid()) select * from #t drop table #t --给查询结果集增加自增长列 --无主键时: select IDENTITY(int,1,1)as ID, cardId, name, birthday, sex into #t from student1 select * from #t --有主键时: select (select SUM(1) from student1 where ID<= a.ID) as myID,* from student1 a order by myID --定义表变量 declare @t table( id int not null, msg nvarchar(50) null ) insert into @t values(1,'1') insert into @t values(2,'2') select * from @t --三、循环 --while循环计算1到100的和 declare @a int declare @sum int set @a=1 set @sum=0 while @a<=100 begin set @sum+=@a set @a+=1 end print @sum --四、条件语句 --if,else条件分支 if(1+1=2) begin print '对' end else begin print '错' end --when then条件分支 declare @today int declare @week nvarchar(3) set @today=3 set @week=case when @today=1 then '星期一' when @today=2 then '星期二' when @today=3 then '星期三' when @today=4 then '星期四' when @today=5 then '星期五' when @today=6 then '星期六' when @today=7 then '星期日' else '值错误' end print @week --五、游标 参考[https://www.cnblogs.com/selene/p/4480328.html] --如果不指定游标的作用域,默认为global (1) 使用游标给变量赋值(最标准) declare @id int declare @cardId int declare @name varchar(50) --定义一个游标,并赋值 declare user_cur cursor for select id,cardId,name from student1 --打开游标 open user_cur --判断游标是否执行成功 fetch next from user_cur into @id,@cardId,@name while @@fetch_status=0 begin SELECT @id, @cardId, @name, @@fetch_status --读取游标中的数据 fetch用来读取游标中的某一个行数据 next取下一行 fetch next from user_cur into @id,@cardId,@name end --关闭游标 close user_cur --摧毁游标(释放游标) deallocate user_cur eg1: 使用游标求和 ALTER PROCEDURE [dbo].[ss_1] AS BEGIN DECLARE @zj int = 0; DECLARE @name VARCHAR(100) = ''; DECLARE @sal int = 0; declare cur_js cursor for SELECT name, sal FROM student2 open cur_js fetch cur_js into @name, @sal while @@fetch_status=0 BEGIN if @sal > 50 SET @zj = @sal + @zj fetch cur_js into @name, @sal END close cur_js deallocate cur_js SELECT @name as '姓名', @zj AS '总工资' END (2) 使用游标变量 --声明变量用DECLARE,为变量赋值可以用set或SELECT语句,对于游标变量的声明和赋值, --其操作基本相同。在具体使用时,首先要创建一个游标,将其打开后,将游标的值赋给游 --标变量,并通过FETCH语句从游标变量中读取值,最后关闭释放游标。 eg: --声明游标变量 declare @var_cur Cursor --创建游标 declare user_cur cursor for select id,cardId,name from student1 --打开游标 open user_cur --为游标变量赋值 set @var_cur = user_cur --从游标变量中读取值 fetch next from @var_cur --判断fetch语句是否执行成功 while @@fetch_status=0 begin fetch next from @var_cur end --关闭游标 close user_cur --释放游标 deallocate user_cur (3)用游标为变量赋值 --在游标的操作过程中,可以使用FETCH语句将数据值存入变量, --这些保持表中列值的变量可以在后面的程序中使用 declare @id int declare @ucardId int declare @uname varchar(50) --定义一个游标,并赋值 declare user_cur cursor for select id,cardId,name from student1 WHERE id = 2 --打开游标 open user_cur --判断游标是否执行成功 fetch next from user_cur into @id,@ucardId,@uname print 'id 学号 姓名' while @@fetch_status=0 begin print @uname fetch next from user_cur into @id,@ucardId,@uname end --关闭游标 close user_cur --摧毁游标(释放游标) deallocate user_cur (4)用ORDER BY 子句改变游标中的执行顺序 游标是一个查询结果集,那么能不能对结果进行排序呢?答案是否定的。与基本的SELECT 语句中的排序方法相同,ORDER BY子句添加到查询中可以对游标查询的结果排序。 注意:只有出现在游标中的SELECT语句中的列才能作为ORDER BY 子句的排序列,而对与非 游标的SELECT语句中,表中任何列都可以作为ORDER BY 的排序列,即使该列没有出现在SELECT语句的查询结果列中. --定义一个游标,并赋值 declare user_cur cursor for select id,cardId,name from student1 ORDER BY id DESC --打开游标 open user_cur --判断游标是否执行成功 fetch next from user_cur while @@fetch_status=0 begin --读取游标中的数据 fetch用来读取游标中的某一个行数据 next取下一行 fetch next from user_cur end --关闭游标 close user_cur --摧毁游标(释放游标) deallocate user_cur (5)用游标修改数据 --修改id等于@sid处name字段的值 declare @id int declare @sid int = 1 --定义一个游标,并赋值 declare user_cur cursor for select id from student1 --打开游标 open user_cur --判断游标是否执行成功 fetch next from user_cur into @id while @@fetch_status=0 begin if @id = @sid begin --修改表中字段的值 update student1 set name = '王楠' where id = @sid end fetch next from user_cur into @id end --关闭游标 close user_cur --摧毁游标(释放游标) deallocate user_cur SELECT * FROM student1 (6)用游标删除数据 使用游标删除数据时,既可以删除游标结果集中的数据,也可以删除基本表中的数据. declare @id int declare @sid int = 1 --定义一个游标,并赋值 declare user_cur cursor for select id from student1 --打开游标 open user_cur --判断游标是否执行成功 fetch next from user_cur into @id while @@fetch_status=0 begin if @id = @sid begin --删除表中的值 delete from student1 where id = @sid end fetch next from user_cur into @id end --关闭游标 close user_cur --摧毁游标(释放游标) deallocate user_cur SELECT * FROM student1 --六、触发器 --触发器中的临时表: --Inserted:存放进行insert和update 操作后的数据 --Deleted:存放进行delete 和update操作前的数据 --创建触发器 Create trigger User_OnUpdate On student1 for Update As declare @msg nvarchar(50) --@msg记录修改情况 select @msg = N'姓名从“' + Deleted.Name + N'”修改为“' + Inserted.Name + '”' from Inserted,Deleted --插入日志表 insert into [LOG](MSG)values(@msg) --删除触发器 drop trigger User_OnUpdate --七、存储过程 --创建带output参数的存储过程 CREATE PROCEDURE PR_Sum @a int, @b int, @sum int output AS BEGIN set @sum=@a+@b END --创建Return返回值存储过程 CREATE PROCEDURE PR_Sum2 @a int, @b int AS BEGIN Return @a+@b END --执行存储过程获取output型返回值 declare @mysum int execute PR_Sum 1,2,@mysum output print @mysum --执行存储过程获取Return型返回值 declare @mysum2 int execute @mysum2= PR_Sum2 1,2 print @mysum2 --八、自定义函数 函数的分类: 1)标量值函数 2)表值函数 a:内联表值函数 b:多语句表值函数 3)系统函数 --新建标量值函数 create function FUNC_Sum1 ( @a int, @b int ) returns int as begin return @a+@b end --新建内联表值函数 create function FUNC_UserTab_1 ( @myId int ) returns table as return (select * from ST_User where ID<@myId) --新建多语句表值函数 create function FUNC_UserTab_2 ( @myId int ) returns @t table ( [ID] [int] NOT NULL, [Oid] [int] NOT NULL, [Login] [nvarchar](50) NOT NULL, [Rtx] [nvarchar](4) NOT NULL, [Name] [nvarchar](5) NOT NULL, [Password] [nvarchar](max) NULL, [State] [nvarchar](8) NOT NULL ) as begin insert into @t select * from ST_User where ID<@myId return end --调用表值函数 select * from dbo.FUNC_UserTab_1(15) --调用标量值函数 declare @s int set @s=dbo.FUNC_Sum1(100,50) print @s --删除标量值函数 drop function FUNC_Sum1 谈谈自定义函数与存储过程的区别: 一、自定义函数: 1. 可以返回表变量 2. 限制颇多,包括 不能使用output参数; 不能用临时表; 函数内部的操作不能影响到外部环境; 不能通过select返回结果集; 不能update,delete,数据库表; 3. 必须return 一个标量值或表变量 自定义函数一般用在复用度高,功能简单单一,争对性强的地方。 二、存储过程 1. 不能返回表变量 2. 限制少,可以执行对数据库表的操作,可以返回数据集 3. 可以return一个标量值,也可以省略return 存储过程一般用在实现复杂的功能,数据操纵方面。 复制代码