diff --git "a/14\350\226\233\346\231\226/\344\275\234\344\270\232/9.26\345\255\230\345\202\250\350\277\207\347\250\213.md" "b/14\350\226\233\346\231\226/\344\275\234\344\270\232/9.26\345\255\230\345\202\250\350\277\207\347\250\213.md" new file mode 100644 index 0000000000000000000000000000000000000000..bdc0f5ed39e60be90ec586c3510ea1bf639f4f0f --- /dev/null +++ "b/14\350\226\233\346\231\226/\344\275\234\344\270\232/9.26\345\255\230\345\202\250\350\277\207\347\250\213.md" @@ -0,0 +1,122 @@ +``` +select * from AccountInfo +select * from BankCard +select * from CardExchange +select * from CardStateChange +select * from CardTransfer +--1. 定义存储过程实现查询出账户余额最低的银行卡账户信息,显示银行卡号,姓名,账户余额 +go +create proc p_zuidi +as +select top 1 cardno,(select RealName from AccountInfo where BankCard.AccountId=AccountInfo.AccountId),cardmoney from BankCard +order by CardMoney +go +exec p_zuidi +--2. 模拟银行卡存钱操作,传入银行卡号,存钱金额,实现存钱操作 +go +create proc p_cun +@a money, +@b varchar(20) +as + update BankCard set CardMoney+=@a where CardNo=@b + insert into CardExchange values(@b,@a,0,getdate()) + select * from BankCard where CardNo=@b + select * from CardExchange where CardNo=@b +go + +exec p_cun 1000,'6225125478588888' +--3. 模拟银行卡取钱操作,传入银行卡号,取钱金额,实现取钱操作,取钱成功,返回1,取钱失败返回-1 +go +create proc p_qu +@a money, +@b varchar(20) +as +declare @c money +set @c =(select cardmoney from BankCard where CardNo=@b) +if @c>=@a +begin + update BankCard set CardMoney-=@a where CardNo=@b + insert into CardExchange values(@b,0,@a,getdate()) + return 1 +end +else +begin + return -1 +end +go +declare @l int +exec @l= p_qu 1000,'6225125478588888' +if @l=1 +begin + +print '取钱成功' +end +else if @l=-1 +begin +print '取钱失败' +end +--4. **查询出某时间段的银行存取款信息以及存款总金额**,取款总金额,传入开始时间,结束时间,显示存取款交易信息的同时,返回存款总金额,取款总金额。 +go +create proc p_cq +@a date,@b date,@c money output, @d money output +as + select * from CardExchange where ExchangeTime between @a and @b + set @c =(select sum(MoneyInBank) from CardExchange where ExchangeTime between @a and @b) + set @d=(select sum(MoneyoutBank) from CardExchange where ExchangeTime between @a and @b) + +go +declare @c money,@d money +exec p_cq '2022-09-07','2022-09-27',@c output,@d output +print '存款总金额'+cast(@c as varchar(20))+',取款总金额 '+cast(@d as varchar(20)) +--5. **密码升级**,传入用户名和密码,如果用户名密码正确,并且密码长度<8,自动升级成8位密码 +--(提示:随机生成 0-9 的整数: float(rand()*10)) rand():随机生成0.0-1.0的小数 float:向下取整) +go +create proc p_mm +@a varchar(20), +@b varchar(20) output +as + +if @b=(select CardPwd from BankCard where CardNo=@a) +begin + if len(@b)<8 + begin +declare @y int +set @y= (rand()*10)*10000000 +declare @ll int +set @ll= (rand()*10) + if len(@y)<8 + begin + set @y*=10 + set @y+=@ll + end + update BankCard set CardPwd=@y where CardNo=@a + print '密码正确,已自动升级成8位密码' + end + else + begin + print '无需升级' + end +end +else +begin + print '密码和卡号不匹配' +end +go +declare @a varchar(20)='6225125478588888' +declare @b varchar(20)=(select CardPwd from BankCard where CardNo=@a) +exec p_mm @a ,@b output + + + +declare @l int +set @l= (rand()*10)*10000000 +declare @ll int +set @ll= (rand()*10) + + if @l<10000000 + begin + set @l*=10 + set @l+=@ll + end + print @l +``` diff --git "a/14\350\226\233\346\231\226/\347\254\224\350\256\260/9.22\346\255\273\351\224\201.md" "b/14\350\226\233\346\231\226/\347\254\224\350\256\260/9.22\346\255\273\351\224\201.md" new file mode 100644 index 0000000000000000000000000000000000000000..66f5c4327c981e0d71125e7f6afa092c4704f449 --- /dev/null +++ "b/14\350\226\233\346\231\226/\347\254\224\350\256\260/9.22\346\255\273\351\224\201.md" @@ -0,0 +1,80 @@ +## 关联子查询 + +#### 同表关联一个一个对照查询 + +``` +--子查询 +select * from tb_student +where birth in (select min(birth) from tb_student group by gender) + +--关联子查询 +select * from tb_student t1 where birth =(select min(birth) from tb_student t2 + where t2.gender=t1.gender) + --=返回标量 + +--先在t1(外层查询)查询数据: gender已经查询出来了 +--在内部一行一行查询 + + +--部门工资最高的员工:部门名称,员工名称,薪水 +select * from Department d join Employee e on d.id=e.departmentId +where salary in (select max(salary) from Employee group by departmentId) + +--关联子查询 +select * from Department d join Employee e on d.id=e.departmentId +where salary = +(select max(salary) from +Employee e1 where e.departmentId=e1.departmentId) + +同表关联一个一个对照查询 +``` + +## 排序 + +``` +over +frame: rows between unbounded preceding and current row +unbounded preceding:第一行 +current row:当前行 +select score,max(score) +over (order by stuid asc rows between current row and 1 following) frame +from stuscore + +frame:rows, range +between ... and ... +unbounded preceding: 第一行 +unbounded following: 最后一行 +CURRENT ROW: 当前行 +ROWS:逻辑位置存储 RANGE:物理位置存储 + 行号 preceding: 前面几行 + 行号 following: 后面几行 +``` + +## 死锁(事务) + +#### 死锁产生的原因 + +A事务和B事务需要使用资源1,2,但是A事务占用了资源1,B事务占用了资源2,两个事务同时等待对方资源释放。 死锁是指在一组进程中的各个进程均占有不会释放的资源,但因互相申请被其他进程所占用不会释放的资源而处于的一种永久等待状态。 + +#### 防止死锁产生: + +语句保持一致 事务语句不要写太长 + +``` +--A用户 +--begin transaction: A-->语句1 +--语句1 update StuInfo set classid = 2 where StuName='黄炜杰' +--语句2 update StuInfo set classid = 2 where StuName='李雅芸' +--commit transaction + + +--B用户 +--begin transaction: B-->语句1 +--语句1: update StuInfo set classid = 2 where StuName='李雅芸' +--语句2: update StuInfo set classid = 2 where StuName='黄炜杰' +--commit transaction +``` + +事务只能整体完成 + +当一个事务无法结束时,另一个与之有关的事务就会陷入死锁,占用资源永久等待 diff --git "a/14\350\226\233\346\231\226/\347\254\224\350\256\260/9.26\345\255\230\345\202\250\350\277\207\347\250\213.md" "b/14\350\226\233\346\231\226/\347\254\224\350\256\260/9.26\345\255\230\345\202\250\350\277\207\347\250\213.md" new file mode 100644 index 0000000000000000000000000000000000000000..1c0547c9675da22cd4eb27b1b4eee60585abcb54 --- /dev/null +++ "b/14\350\226\233\346\231\226/\347\254\224\350\256\260/9.26\345\255\230\345\202\250\350\277\207\347\250\213.md" @@ -0,0 +1,131 @@ +## 存储过程(Stored Procedure) + +#### 什么是存储过程 + +存储过程是**预编译**SQL语句集合,这些语句存储在一个名称(存储过程的名称)下并作为单元来处理。存储过程代替了传统的逐条执行SQL语句的方式,一个存储过程中可以包含查询、插入、删除、更新等操纵的一系列SQL语句,当这个存储过程被调用执行时,这些操作也会同时执行。 + +封装好 --> 调用 + +#### 存储过程的分类 + +##### 系统存储过程 + +系统存储过程是用来管理SQL Server与显示有关数据库和用户的信息的存储过程。 + +常见的系统存储过程有 + +``` +sp_databases 列出服务上的所有数据库 +sp_helpdb --报告有关指定数据库或所有数据库的信息 +sp_renamedb 更改数据库的名称 +sp_tables --返回当前环境下可查询的对象的列表 +sp_columns 返回某个表列的信息 +sp_help --返回某个表的所有信息 +sp_helpconstraint 查看某个表的约束 +sp_helpindex --查看某个表的索引 +sp_stored_procedures 列出当前环境中的所有存储过程 +sp_password --添加或修改登录账户的密码 +sp_rename 重命名存储过程 +sp_helptext 显示默认值,未加密的存储过程、用户定义的存储过程、触发器或视图的实际文本。 +``` + +##### 自定义存储过程 + +**创建存储过程** + +1.没有输入参数,没有输出参数的存储过程。 + +``` +create proc <存储过程名称> +as + +go +``` + +练习: 定义存储过程查询 年龄最小的学生信息 + +2.有输入参数,没有输出参数的存储过程 + +``` +create proc <存储过程名称> +<变量1> <数据类型> +<变量2> <数据类型> +... +as + +go +``` + +3.有输入参数,没有输出参数,但是有返回值的存储过程(返回值必须整数)。 + +``` +create proc <存储过程名称> +<变量1> <数据类型> +<变量2> <数据类型> +... +as + +return 整数 +go +``` + +4.有输入参数,有输出参数的存储过程 & 一个变量具备同时输入输出参数的存储过程 + +``` +create proc <存储过程名称> +<变量1> <数据类型> output +<变量2> <数据类型> output +... +as + +return 整数 +go +``` + +**执行存储过程** + +``` +--无参 +exec <存储过程名称> +--带参 +exec <存储过程名称> <形参1>,<形参2>,... +--带参带返回值 +declare @变量 +exec @变量 = <存储过程名称> <形参1>,<形参2>,... +--有输入参数,有输出参数的存储过程 +declare @变量 +exec <存储过程名称> <形参1>,<形参2>,@变量 output +--一个变量同时具备输入输出功能 +declare @变量 <数据类型> = 值 +exec <存储过程名称> <形参1>,<形参2>,@变量 output +``` + +**删除存储过程** + +``` +drop procedure <存储过程名称> +``` + +#### 存储过程的优点 + +允许模块化程序设计 + +执行速度更快 + +减少网络流通量 + +提高系统安全性 + +#### 存储过程与函数的区别 + +1.储存过程可以有返回值也可以无返回值。函数必须有返回值。 + +2.存储过程的实现比较复杂,而函数的实现比较有针对性。 + +3.储存过程可以输入输出参数,而函数只可以输入参数。 + +4.过程允许在其中选择以及DML语句,而函数只可以在其中select语句。 + +5.可以在存储过程中调用函数,不可以在函数中调用存储过程。 + +6.函数可以作为条件在语句中使用,但是存储过程不可以。