diff --git "a/\347\224\260\351\221\253\345\274\272/\344\275\234\344\270\232/0926\345\255\230\345\202\250\350\277\207\347\250\213.md" "b/\347\224\260\351\221\253\345\274\272/\344\275\234\344\270\232/0926\345\255\230\345\202\250\350\277\207\347\250\213.md" new file mode 100644 index 0000000000000000000000000000000000000000..513c71841182f360b7cac0332ccc96902ad1229f --- /dev/null +++ "b/\347\224\260\351\221\253\345\274\272/\344\275\234\344\270\232/0926\345\255\230\345\202\250\350\277\207\347\250\213.md" @@ -0,0 +1,108 @@ +```sql +use BankTest +go + +select * from AccountInfo --个人信息 +select * from BankCard --银行卡信息 +select * from CardStateChange --银行卡状态更改表 +select * from CardTransfer --转账表 +select * from CardExchange --交易记录 + +``` + +1. + +```sql +--1. 定义存储过程实现查询出账户余额最低的银行卡账户信息,显示银行卡号,姓名,账户余额 +go +create proc proc_MinMoneyCard +as + select CardNo,RealName,CardMoney from BankCard b + inner join AccountInfo a on a.AccountId=b.AccountId + where CardMoney=(select min(CardMoney) from BankCard ) +go + +``` + +2. + +```sql +--2. 模拟银行卡存钱操作,传入银行卡号,存钱金额,实现存钱操作 +go +create proc proc_Inmoney +@cardno varchar(20), +@money money +as + update BankCard set CardMoney = CardMoney+@money where CardNo=@cardno + insert CardExchange values (@cardno,@money,0,getdate()) +go +exec proc_Inmoney '6225125478544587','1000' + +``` + +3. + +```sql +--3. 模拟银行卡取钱操作,传入银行卡号,取钱金额,实现取钱操作,取钱成功,返回1,取钱失败返回-1 +go +create proc proc_Outmoney +@cardno varchar(20), +@money money +as + if @money<=(select CardMoney from BankCard where CardNo=@cardno) + begin + update BankCard set CardMoney = CardMoney-@money where CardNo=@cardno + insert CardExchange values (@cardno,0,@money,getdate()) + return 1 + end + else + begin + return -1 + end +go +declare @a int +exec @a=proc_Outmoney '6225125478544587','1000' +print @a + + +``` + +4. + +```sql +--4. **查询出某时间段的银行存取款信息以及存款总金额**,取款总金额, +--传入开始时间,结束时间,显示存取款交易信息的同时,返回存款总金额,取款总金额。 +go +create proc proc_CardMoneyInfo +@stare date, +@end date, +@inmoney money output, +@outmoney money output +as + select * from CardExchange where ExchangeTime>=@stare and ExchangeTime<=@end + select @inmoney=sum(MoneyInBank) from CardExchange where ExchangeTime>=@stare and ExchangeTime<=@end + select @outmoney=sum(MoneyOutBank) from CardExchange where ExchangeTime>=@stare and ExchangeTime<=@end +go +declare @inmoney money,@outmoney money +exec proc_CardMoneyInfo '2022-9-20','2022-9-22',@inmoney output,@outmoney output +print '存款总金额'+convert(varchar,@inmoney) +','+'取款总金额'+convert(varchar,@outmoney) + +``` + +5. + +```sql +--5. **密码升级**,传入用户名(银行卡号)和密码,如果用户名密码正确,并且密码长度<8,自动升级成8位密码 +--(提示:生随机生成 0-9 的整数: float(rand()*10)) rand():随机成0.0-1.0的小数 float:向下取整) +go +create proc proc_pwd +@cardno varchar(20), +@pwd varchar(10) +as + if exists( select * from BankCard where CardNo=6225125478544587 and CardPwd=12356 and len(cardpwd)<8) + begin + update BankCard set CardPwd=123 where CardNo=6225125478544587 and CardPwd=12356 and len(cardpwd)<8 + end +go +``` + diff --git "a/\347\224\260\351\221\253\345\274\272/\344\275\234\344\270\232/0927\350\247\246\345\217\221\345\231\250.md" "b/\347\224\260\351\221\253\345\274\272/\344\275\234\344\270\232/0927\350\247\246\345\217\221\345\231\250.md" new file mode 100644 index 0000000000000000000000000000000000000000..54f6976f60600dd512f4b327cd2faf9caeeb6b99 --- /dev/null +++ "b/\347\224\260\351\221\253\345\274\272/\344\275\234\344\270\232/0927\350\247\246\345\217\221\345\231\250.md" @@ -0,0 +1,116 @@ +建立库、表 + +```sql +create database text02 +go +use text02 +go +--部门 +create table Department +( + DepartmentId varchar(10) primary key , --主键,自动增长 + DepartmentName nvarchar(50), --部门名称 +) +--人员信息 +create table People +( + PeopleId int primary key identity(1,1), --主键,自动增长 + DepartmentId varchar(10), --部门编号,外键,与部门表关联 + PeopleName nvarchar(20), --人员姓名 + PeopleSex nvarchar(2), --人员性别 + PeopleSalary money, --薪水 +) +insert into Department(DepartmentId,DepartmentName) +values('001','总经办') +insert into Department(DepartmentId,DepartmentName) +values('002','市场部') +insert into Department(DepartmentId,DepartmentName) +values('003','人事部') +insert into Department(DepartmentId,DepartmentName) +values('004','财务部') + +insert into People(DepartmentId,PeopleName,PeopleSex,PeopleSalary) +values('001','刘备','男',8000) +insert into People(DepartmentId,PeopleName,PeopleSex,PeopleSalary) +values('001','关羽','男',5000) +insert into People(DepartmentId,PeopleName,PeopleSex,PeopleSalary) +values('002','张飞','男',3000) + +select * from Department +select * from People + +``` + +1. + +```sql +--(1)假设有部门表和员工表,在添加员工的时候,该员工的部门编号如果在部门表中找不到, +--则自动添加部门信息,部门名称为"新部门"。 +go +create trigger tri_department +on People after insert +as +begin + if not exists (select * from inserted where DepartmentId in(select DepartmentId from Department)) + begin + declare @id varchar(10) + set @id =(select DepartmentId from inserted) + insert Department values (@id,'新部门') + end +end +go +--drop trigger tri_department +insert People values ('007','jan','女',6000) + +``` + +2. + +```sql +--(2)触发器实现,删除一个部门的时候将部门下所有员工全部删除。 +go +create trigger tri_DeletePeople +on Department after delete +as +begin + delete People where DepartmentId = (select DepartmentId from deleted) +end +go +--drop trigger tri_DeletePeople +delete Department where DepartmentName='人事部' + +``` + +3. + +```sql +--(3)创建一个触发器,删除一个部门的时候判断该部门下是否有员工,有则不删除,没有则删除。 +go +create trigger tri_DepartmentByPeople +on Department instead of delete +as +begin + if not exists(select * from People where DepartmentId =(select DepartmentId from deleted)) + begin + delete Department where DepartmentId=(select DepartmentId from deleted) + end +end +go +delete Department where DepartmentName='新部门' + +``` + +4. + +```sql +--(4)修改一个部门编号之后,将该部门下所有员工的部门编号同步进行修改 +go +create trigger tri_UpdateDept +on Department after update +as + update People set DepartmentId = (select DepartmentId from inserted) + where DepartmentId = (select DepartmentId from deleted) +go +update Department set DepartmentId = 'jj007' where DepartmentId='007' +``` + diff --git "a/\347\224\260\351\221\253\345\274\272/\347\254\224\350\256\260/09-22\346\255\273\351\224\201.md" "b/\347\224\260\351\221\253\345\274\272/\347\254\224\350\256\260/09-22\346\255\273\351\224\201.md" new file mode 100644 index 0000000000000000000000000000000000000000..da81014136b94868276f7be50ab6b92cedecbac2 --- /dev/null +++ "b/\347\224\260\351\221\253\345\274\272/\347\254\224\350\256\260/09-22\346\255\273\351\224\201.md" @@ -0,0 +1,41 @@ +### 关联子查询 + +#### 排序 + +over + +frame:rows between **unbounded preceding** and **current row** + +select 列名 over (order by 列名 asc rows between **current row** and **1 following**) frame from 表名 + +frame:rows, range + +between ... and ... + +**unbounded preceding**: 第一行 + +**unbounded following**: 最后一行 + +**current row**:当前行 + +ROWS:逻辑位置存储 RANGE:物理位置存储 + +行号 **preceding**: 前面几行 行号 **following**: 后面几行 + +## 什么是死锁 + +死锁是指两个或者多个事务在同一资源上的相互占用,并请求锁定对方占用的资源,从而导致恶性循环的现象 + +##### sql server死锁表现一: + +>    一个用户A 访问表A(锁住了表A),然后又访问表B。    另一个用户B 访问表B(锁住了表B),然后企图访问表A,    这时用户A由于用户B已经锁住表B,它必须等待用户B释放表B,才能继续,好了他老人家就只好老老实实在这等了,同样用户B要等用户A释放表A才能继续,这就造成死锁了。 + +**sql server死锁表现二:** + +>    用户A读一条纪录,然后修改该条纪录。    这时用户B修改该条纪录,这里用户A的事务里锁的性质由共享锁企图上升到独占锁(for update),而用户B里的独占锁由于A有共享锁存在所以必须等A释    放掉共享锁,而A由于B的独占锁而无法上升的独占锁也就不可能释放共享锁,于是出现了死锁。    这种死锁比较隐蔽,但其实在稍大点的项目中经常发生。 + +**sql server死锁解决方法:**   让用户A的事务(即先读后写类型的操作),在select 时用Update lock 语法如下:    select * from table1 with(updlock) where .... + +##### 防止死锁的发生: + +语句保持一致,事务语句不要写太长 \ No newline at end of file diff --git "a/\347\224\260\351\221\253\345\274\272/\347\254\224\350\256\260/09-26\345\255\230\345\202\250\350\277\207\347\250\213\357\274\237.md" "b/\347\224\260\351\221\253\345\274\272/\347\254\224\350\256\260/09-26\345\255\230\345\202\250\350\277\207\347\250\213\357\274\237.md" new file mode 100644 index 0000000000000000000000000000000000000000..fef67087dbe4e1d2839f7e90231251d5ddf202f5 --- /dev/null +++ "b/\347\224\260\351\221\253\345\274\272/\347\254\224\350\256\260/09-26\345\255\230\345\202\250\350\277\207\347\250\213\357\274\237.md" @@ -0,0 +1,135 @@ +### 1.什么是存储过程? + +存储过程是一个预编译的SQL语句,优点是允许模块化的设计,就是说只需创建一次,以后在程序中就可以调用多次。如果某次操作需要执行多次SQL,使用存储过程比单纯SQL语句执行要快。可以用一个“execute 存储过程名 参数”命令来调用存储过程。 + +### 2.存储过程的种类 + +##### 1 系统存储过程 + +以sp_开头,用来进行系统的各项设定.取得信息.相关管理工作。 + +##### 2 自定义存储过程(本地存储过程) + +以cp_开头,是用户为了完成某一特定功能而创建的存储过程,一般所说的存储过程就是指本地存储过程。 + +##### 3 临时存储过程 + +分为两种存储过程: + +一是本地临时存储过程,以井字号(#)作为其名称的第一个字符,则该存储过程将成为一个存放在tempdb数据库中的本地临时存储过程,且只有创建它的用户才能执行它; + +二是全局临时存储过程,以两个井字号(##)号开始,则该存储过程将成为一个存储在tempdb数据库中的全局临时存储过程,全局临时存储过程一旦创建,以后连接到服务器的任意用户都可以执行它,而且不需要特定的权限。 + +##### 4 远程存储过程 + +在SQL Server2005中,远程存储过程(Remote Stored Procedures)是位于远程服务器上的存储过程,通常可以使用分布式查询和EXECUTE命令执行一个远程存储过程。 + +##### 5 扩展存储过程 + +扩展存储过程(Extended Stored Procedures)是用户可以使用外部程序语言编写的存储过程,而且扩展存储过程的名称通常以xp_开头 + +### 3.如何创建、修改、删除、调用存储过程? + +``` +–创建存储过程 +create proc 存储过程名字 +as +语句 + +–修改存储过程 +alter proc 存储过程名字 +as +语句 + +–卸载存储过程 +drop proc 存储过程名字 + +–调用存储过程 +exec 存储过程名称 +``` + +例题 + +1. + +```sql +--创建存储过程 1.没有参数,没有返回值 +go +create proc proc_GetMaxBirth +as +select max(birth) 最小出生日期 from tb_student +go + +--执行 +exec proc_GetMaxBirth --带参 + +--删除 +drop procedure proc_GetMaxBirth + +``` + +2. + +```sql + +--2.带参,无返回 +select * from tb_bibliography +select name,publishing from tb_bibliography where category='TP' + +create proc proc_GetBookInfoByCategory +@cg varchar(30) +as +select name,publishing from tb_bibliography where category=@cg + +go + +exec proc_GetBookInfoByCategory 'I' + +``` + +3. + +```sql +--3中返回:1.直接在存储过程里写查询语句,执行的时候会在结果显示 2.return语句,只能返回int型数据 + +--输入学号,查询该生是否还能借书(最多能借2本书),返回还能借几本 0 + +select count(*) 已借书 from tb_record where stu_num='' + +create proc proc_GetRestBoo +@stunum varchar(30) +as + declare @rest varchar(2) + set @rest = 2 - (select count(*) 已借书 from tb_record where stu_num=@stunum) + return --返回的是整型数据 +go + +declare @restborrow varchar(20) +exec @restborrow = proc_GetRestBoo '17100105' +print @restborrow +``` + + + +### 3.存储过程的分类 + +##### 系统存储过程 + +系统存储过程是用来管理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 显示默认值,未加密的存储过程、用户定义的存储过程、触发器或视图的实际文本。 +``` \ No newline at end of file diff --git "a/\347\224\260\351\221\253\345\274\272/\347\254\224\350\256\260/09-27\350\247\246\345\217\221\345\231\250.md" "b/\347\224\260\351\221\253\345\274\272/\347\254\224\350\256\260/09-27\350\247\246\345\217\221\345\231\250.md" new file mode 100644 index 0000000000000000000000000000000000000000..60d9c67608f1cf30c73b051ce331c8382a603b46 --- /dev/null +++ "b/\347\224\260\351\221\253\345\274\272/\347\254\224\350\256\260/09-27\350\247\246\345\217\221\345\231\250.md" @@ -0,0 +1,88 @@ +### 一、触发器(==trigger==) + +#### 1、概念 + +- **触发器**( trigger )是作为**对数据库修改的连带效果**而**由系统自动执行**的一条语句。它是一种特殊的**存储过程**。也是一个**事务**(可以回滚),触发器经常用于加强数据的完整性约束和业务规则等 + +#### 2、触发器类型 + +##### 1、DML触发器(增inserte,删deleted,改update) + +- 插入操作(Insert) inserted 表有数据,deleted 表无数据 +- 删除操作(Delete) inserted 表无数据,deleted 表有数据 +- 更新操作(Update) inserted 表有数据(新数据),deleted 表有数据(旧数据) + +==**inserte**==:向表中插入数据时触发 + +``` +go +create trigger (触发器名,一般以tri_开头) +on 表名 alter inserte +as + +go + +插入语句(符合条件会触发上面触发器) +``` + +**==deleted==**:从表中删除数据时被触发 + +``` +go +create trigger (触发器名,一般以tri_开头) +on 表名 alter deleted +as + +go + +删除语句(符合条件会触发上面触发器) +``` + +**==update==**:更新数据时会触发 + +``` +create trigger (触发器名,一般以tri_开头) +on 表名 after update +as + declare @值1 数据类型=(select 所需修改的数据列 from inserted) + declare @值2 数据类型=(select 所需修改的数据列 from deleted) + + begin + update 表名 set 修改的列名=@值 from inserted + where 表名.修改的列名 = @值2 + end + +go + + +update 表名 set 修改的列名='修改后的值' where 修改的列名='修改前的值' +``` + +##### 2、DDL触发器 + +- DDL触发器是当服务器或者数据库中发生数据定义语言(主要是以create,drop,alter开头的语句)事件时被激活使用,使用DDL触发器可以防止对数据架构进行的某些更改或记录数据中的更改或事件操作 + +##### 3、登录触发器 + +- 登录触发器将为响应 LOGIN 事件而激发存储过程。与 SQL Server 实例建立用户会话时将引发此事件。登录触发器将在登录的身份验证阶段完成之后且用户会话实际建立之前激发。因此,来自触发器内部且通常将到达用户的所有消息(例如错误消息和来自 PRINT 语句的消息)会传送到 SQL Server 错误日志。如果身份验证失败,将不激发登录触发器。 + +#### 3,创建触发器 + +``` +CREATE TRIGGER <触发器名称> + +ON table_name + +[WITH ENCRYPTION] + +FOR [DELETE, INSERT, UPDATE] + +AS + + T-SQL语句 + +GO +--WITH ENCRYPTION表示加密触发器定义的SQL文本 + +--DELETE, INSERT, UPDATE指定触发器的类型 +``` \ No newline at end of file