From 5777c4a0cec74386c4291908808877a045cf8576 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=88=E5=8D=8E=E4=BC=9F?= <1931626338@qq.com> Date: Sun, 9 Oct 2022 23:33:16 +0800 Subject: [PATCH 1/2] =?UTF-8?q?=E8=87=AA=E5=AE=9A=E4=B9=89=E5=87=BD?= =?UTF-8?q?=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../2022-10-06 \345\207\275\346\225\260 .md" | 756 ++++++++++++++++++ .../SQLQuery11.sql" | 162 ++++ 2 files changed, 918 insertions(+) create mode 100644 "12 \351\231\210\345\215\216\344\274\237/2022-10-06 \347\254\254\345\215\201\344\270\200\346\254\241\344\275\234\344\270\232\345\222\214\347\254\224\350\256\260/2022-10-06 \345\207\275\346\225\260 .md" create mode 100644 "12 \351\231\210\345\215\216\344\274\237/2022-10-06 \347\254\254\345\215\201\344\270\200\346\254\241\344\275\234\344\270\232\345\222\214\347\254\224\350\256\260/SQLQuery11.sql" diff --git "a/12 \351\231\210\345\215\216\344\274\237/2022-10-06 \347\254\254\345\215\201\344\270\200\346\254\241\344\275\234\344\270\232\345\222\214\347\254\224\350\256\260/2022-10-06 \345\207\275\346\225\260 .md" "b/12 \351\231\210\345\215\216\344\274\237/2022-10-06 \347\254\254\345\215\201\344\270\200\346\254\241\344\275\234\344\270\232\345\222\214\347\254\224\350\256\260/2022-10-06 \345\207\275\346\225\260 .md" new file mode 100644 index 0000000..2d59065 --- /dev/null +++ "b/12 \351\231\210\345\215\216\344\274\237/2022-10-06 \347\254\254\345\215\201\344\270\200\346\254\241\344\275\234\344\270\232\345\222\214\347\254\224\350\256\260/2022-10-06 \345\207\275\346\225\260 .md" @@ -0,0 +1,756 @@ +# 2022.9.16 + +## 创建数据库 + +```SQL +create database 数据库名 +``` + +## 创建数据表 + +```SQL +create table 表名( +) +``` + +## 查询数据 + +```sql +select * from 表名 +``` + +## 增删改查 + +```SQL +insert into 表名 ({字段1},{字段1},{字段1},....) values (值1,值1,值1,....) +alter table (表名) add (列名) varchar(255) ; +delete from 表名 where 删除条件 +drop table (表名) 删除整个表 +UPDATE 表名 SET 字段1=修改的值1,字段2=修改的值2,.. . .. WHERE 修改的条件 +``` + + + +## 主键,自增,不允许为空,默认值,外键,唯一约束 + +```sql +1.primary key 主键 +2.identity(1,1) 自增 初始ID,自增多少 +3.not null 不允许为空 +4.default('') 默认值 +5.userId(表名) int(字段) references(外键) userInfo(表名)(userNo)列名 外键 +6.unique 唯一约束 +``` + +# 2022.9.17 + +## SQL条件查询 + +```sql +=:等于,比较是否相等及赋值 +!=:比较不等于 +>:比较大于 +<:比较小于 +>=:比较大于等于 +<=:比较小于等于 +IS NULL:比较为空 +IS NOT NULL:比较不为空 +in:比较是否在其中 +like:模糊查询 +BETWEEN...AND...:比较是否在两者之间 50-100 BETWEEN 50 AND 100 +and:逻辑与(两个条件同时成立表达式成立) +or:逻辑或(两个条件有一个成立表达式成立) +not:逻辑非(条件成立,表达式则不成立;条件不成立,表达式则成立) +``` + +## 模糊查询 + +```sql +%:代表匹配0个字符、1个字符或多个字符。 +_:代表匹配有且只有1个字符。 +[]:代表匹配范围内 +[^]:代表匹配不在范围内 + +模糊查询,包含查询 +select * from 表名 where 列名 like '%要查询的字段%' + +模糊查询,开头查询 +select * from 表名 where 列名 like '要查询的字段%' + +模糊查询,结尾查询 +select * from 表名 where 列名 like '%要查询的字段' +``` + +## 聚合函数 + +```SQL +count:求数量 +max:求最大值 计算某一列的最大值 +min:求最小值 计算某一列的最小值 +sum:求和 计算某一列的合计值,该列必须为数值类型 +avg:求平均值 计算某一列的平均值,该列必须为数值类型 +``` + +## 升序降序查询 + +```SQL +-- desc 降序 默认升序 asc -- +SELECT * FROM 表名 order by 列名 desc +``` + + + +## ROUND函数用法: + +```SQL +round(num,len,[type]) +其中: +num表示需要处理的数字,len表示需要保留的长度,type处理类型(0是默认值代表四舍五入,非0代表直接截取) +select ROUND(123.45454,3) --123.45500 +select ROUND(123.45454,3,1) --123.45400 +``` + +## CONVERT()与CAST()函数: + +```SQL +--1.保留小数 +convert(decimal(13,2),12.45454) +cast(12.45454 as decimal(13,2)) +--2.强制转换类型 +``` + +## SQL中常用的时间函数 + +```SQL +select DATEDIFF(day, '2019-08-20', getDate()); --获取指定时间单位的差值 +SELECT DATEADD(MINUTE,-5,GETDATE()) --加减时间,此处为获取五分钟前的时间,MINUTE 表示分钟,可为 YEAR,MONTH,DAY,HOUR +select DATENAME(month, getDate()); --当前月份 +select DATENAME(WEEKDAY, getDate()); --当前星期几 +select DATEPART(month, getDate()); --当前月份 +select DAY(getDate()); --返回当前日期天数 +select MONTH(getDate()); --返回当前日期月数 +select YEAR(getDate()); --返回当前日期年数 + +SELECT CONVERT(VARCHAR(22),GETDATE(),20) --2020-01-09 14:46:46 +SELECT CONVERT(VARCHAR(24),GETDATE(),21) --2020-01-09 14:46:55.91 +SELECT CONVERT(VARCHAR(22),GETDATE(),23) --2020-01-09 +SELECT CONVERT(VARCHAR(22),GETDATE(),24) --15:04:07 +Select CONVERT(varchar(20),GETDATE(),14) --15:05:49:330 +``` + +## 连表查询 + +```SQL +内连接查询 +1.select * from 第一张表名 重命名字段1 +2.inner join 第二张表名 重命名字段2 on 重命名字段1.关联的列=重命名字段2.关联的列 +3.where 要筛选的条件、 + +左连接查询 +1.select * from 第一张表名 重命名字段1 +2.left join 第二张表名 重命名字段2 on 重命名字段1.关联的列=重命名字段2.关联的列 +3.where 要筛选的条件、 + +右连接查询 +1.select * from 第一张表名 重命名字段1 +2.right join 第二张表名 重命名字段2 on 重命名字段1.关联的列=重命名字段2.关联的列 +3.where 要筛选的条件、 +``` + +## **时间格式控制字符串:** + +| 名称 | 日期单位 | 缩写 | +| ------------ | ----------- | --------- | +| 年 | year | yyyy 或yy | +| 季度 | quarter | qq,q | +| 月 | month | mm,m | +| 一年中第几天 | dayofyear | dy,y | +| 日 | day | dd,d | +| 一年中第几周 | week | wk,ww | +| 星期 | weekday | dw | +| 小时 | Hour | hh | +| 分钟 | minute | mi,n | +| 秒 | second | ss,s | +| 毫秒 | millisecond | ms | + +## SQL语句执行顺序: + +```sql +(7) SELECT +(8) DISTINCT +(1) FROM +(3) JOIN +(2) ON +(4) WHERE +(5) GROUP BY +(6) HAVING +(9) ORDER BY +(10) LIMIT +``` + +# 2022.9.19 + +## 子查询 + +```sql +标量子查询:返回的是单行单列;标量子查询是指子查询返回的是**单一值**,如一个数字或一个字符串。 + +列子查询:返回的数据时1列n行,放在where之后 + +行子查询:是指子查询返回的结果集是1行N列,该子查询的结果通常是对表的某行数据进行查询而返回的结果集。 + +表子查询(from子查询) +表子查询是指子查询返回是M行N列的结果集,查询语句可嵌套在FROM关 +键字后,且需要定义别名。 +``` + +## all和any的区别 + +```sql +注意:1. =any 与in 等效. +all:是所有 +any:是任意一个 +any表示任何一个满足就返回TRUE,all表示全部都满足才返回TRUE +``` + +## 三个排序函数 + +```sql +row_number():连续,无并列 +dense_rank():有并列,不挑空 +rank():有并列,会挑空 + +--学生的Java成绩,并根据成绩排名 +--row_number() +select StuName 姓名,ROW_NUMBER() over(order by score desc) 排名,score 分数 from StuScore +join stuinfo on StuInfo.StuID = StuScore.StuID +where subject = 'Java' + +--rank() +select StuName 姓名,rank() over(order by score desc) 排名,score 分数 from StuScore +join stuinfo on StuInfo.StuID = StuScore.StuID +where subject = 'Java' + +--DENSE_RANK() + select StuName 姓名,dense_rank() over(order by score desc) 排名,score 分数 from StuScore +join stuinfo on StuInfo.StuID = StuScore.StuID +where subject = 'Java' +``` + +## exists子查询 + +关键字EXISTS构造子查询时,当子查询的结果集不为空时,则EXISTS返回的结果为TRUE,外层查询语句进行查询;当子查询的结果集为空时,则EXISTS返回的结果为FALSE,外层查询语句不进行查询。 + +```SQL + 关羽的银行卡号为"6225547858741263",查询当天是否有收到转账。 + if exists(select * from CardTransfer where CardNoIn = 6225547858741263) + print '有' + else + print '没有' +``` + +# 2022.9.21 + +## 关联子查询_排序 + +```SQL +row_number():连续,无并列 +dense_rank():有并列,不挑空 +rank():有并列,会挑空 +``` + +# 2022.9.22 + +## 变量 + +```sql +全局变量必须以标记@@作为前缀,如@@version +全局变量由**系统定义和维护**,我们**只能读取,不能修改全局变量的值** +全局变量在整个SQL环境下都可以被访问或调用 +--全局变量:只读,由系统定义和维护, @@ + +--@@ERROR:返回执行的上一个语句的错误号 +--@@IDENTITY:返回最后插入的标识值 +--@@MAX_CONNECTIONS:返回允许同时进行的最大用户连接数 +--@@ROWCOUNT:返回受上一语句影响的行数 +--@@SERVERNAME:返回运行 SQL Server 的本地服务器的名称 +--@@SERVICENAME:返回 SQL Server 正在其下运行的注册表项的名称 +--@@TRANCOUNT:返回当前连接的活动事务数 +--@@LOCK_TIMEOUT:返回当前会话的当前锁定超时设置(毫秒) +-------------------------------------------------------------------------------------- +局部变量必须以标记@作为前缀 ,如@age +局部变量的使用是先声明,再赋值 +局部变量只在定义它的局部范围内有效 + +声明一个局部变量:**declare @变量名 数据类型** +--局部变量: 声明(int a),赋值(a = 1) +--declare 变量名 数据类型 +例: + declare @id int --声明一个名为id的整型变量 + declare @name varchar(50) --声明一个可变长度为50的存放姓名的字符串变量 +``` + +# 赋值 + +赋值: + - set @变量名 = 值 + - select @变量名 = 值 + +```sql +--例: + select @id = 1001 + set @name = '周飘' +``` + +set与select赋值的区别: + +set赋值给变量指定的值,select一般用于表中查询出的数据赋值给变量,如果查询结果有多条,取最后一条赋值给变量 + +# 逻辑控制语句 + +## if条件分支 + +```sql +sql中的if-else语句 +if(条件) +begin +语句 +语句 +..... +end +else +begin +语句 +语句 +..... +end +``` + +## while 循环控制语句 + +while:可以通过break和continue控制循环语句中的执行。 + +break:跳出整个循环 + +continue:跳出当前循环 + +```sql +sql中的if-else语句 +while(条件) +begin +语句 +语句 +..... +end +``` + +## 逻辑控制语句 switch case + +``` + +``` + +# 批处理语句 + +go语句特点: + +1. 等待go语句前的代码执行完成后,再执行go后面的代码。 +2. 批处理语句的结束标志。 + +```sql +--下面的@num变量作用域为全局 +--declare @num int +--set @num = 0 + +--下面的@num变量的作用域是局部,只在两个go之间可以使用,最后一行代码会报错 +--.........sql代码 +--go +--declare @num int +--set @num = 0 +--go +--set @num = 1 +``` + +# 2022-9-26 + +## 视图 + +三种类型关系: + +- 表(Table)--基表,存储关系(Base Tables,Sorted relations) +- 视图(Views)--虚拟表,虚拟关系(Virtual relations)(不是物理存在的是虚拟的) +- 临时结果--临时表,(select * from, Temporary results)--用于构建**子查询**的结果 + +with check option --涉及的增删只能对信息学院的学生进行操作 + +## 定义视图 + +```sql +--1.建立视图 +create view <视图名> [(<列名>[,<列名>]...)] +as <子查询> [with check option] + + +create view V_GetInfo(虚拟表) +as +select stu_num(列名), name(列名), school(列名) from tb_student(表名) +select * from V_GetInfo + +--2.使用 +--视图是一张虚拟表 +select * from V_GetInfo --》视图转化: select stu_num, name, school from tb_student + +--3.删除(虚拟表) +--drop view V_GetInfo + +--4.建立信息学院学生的视图 使用,查询虚拟表 +create view V_Info +as +select * from tb_student where school='信息学院' +with check option --涉及的增删只能对信息学院的学生进行操作 + +--5.分组视图:使用group by 建立视图 +create view V_GetTotalPrize(生源地,荣誉总数) +as +select ori_loca , sum(prize) from tb_inf_student group by ori_loca +select * from V_GetTotalPrize + +--6.定义一个反映学生年龄的视图 +create view V_GetAgeByBirth(学号,姓名,年龄) +as +select stu_num,name, (year(getdate()) - year(birth)) from tb_student +select * from V_GetAgeByBirth + +--7.建立信息学院学生的特长属于艺术特长视图 连表查询 +create view V_GetSpecBySch +as +select tb_student.*,hobby,speciality,ori_loca,prize from tb_student join tb_inf_student on tb_student.stu_num = tb_inf_student.stu_num where school='信息学院' and speciality='艺术特长' + +--8.基于视图的视图:视图可作为另一视图建立的表 +create view V_GetOriInBJ +as +select * from V_GetSpecBySch where ori_loca = '北京' +select * from V_GetOriInBJ +``` + +## 查询视图 + +更新视图:不推荐直接在视图进行更新操作,增,删 操作 + +视图一般只用来查询,如果是单表的话,也可以进行增删改。但是有如下限制。 + 1.聚合函数(SUM(), MIN(), MAX(), COUNT()等)。 + +2. DISTINCT + +3. GROUP BY +4. 4 HAVING +5. UNION或UNION ALL (连表) +6. 位于选择列表中的子查询 + 7.Join + 8.FROM子句中的不可更新视图 +7. WHERE子句中的子查询,引用FROM子句中的表。 +8. 仅引用文字值(在该情况下,没有要更新的基本表)。 +9. ALGORITHM = TEMPTABLE(使用临时表总会使视图成为不可更新的)。 + +##### 删除视图 + +```sql +drop view <视图名> +--该语句从数据字典中删除指定的视图定义 +--由该视图导出的其他视图仍在数据字典中,但不能使用,需要删除 +--删除基表时,由该基表导出的所有视图定义都必须显示删除 +``` + +# 2022-9-27到29 + +## 事务 + +**事务( Transaction)由一次或者多次基本操作构成,或者说,事务由一条或者多条 SQL 语句构成。** + +**事务中的所有 SQL 语句是一个整体,共同进退,不可分割,要么全部执行成功,要么全部执行失败。** + +## 事务的属性(ACID) + +一般来说,事务具有四个标准属性,分别是原子性(**A**tomicity,或称不可分割性)、一致性(**C**onsistency)、隔离性(**I**solation,又称独立性)、持久性(**D**urability),简称 **ACID**。具体说明如下: + +##### 1) 原子性 + +一个事务中的所有 SQL 语句,要么全部执行成功,要么全部执行失败,不会结束在中间的某个环节。事务在执行过程中发生错误,会被回滚(Rollback)到事务开始前的状态,就像这个事务从来没有执行过一样。 + +##### 2) 一致性 + +在事务开始之前和事务结束以后,数据库的完整性没有被破坏。这表示写入的数据必须完全符合所有的预设规则,其中包含数据的精确度、串联性以及后续数据库可以自发性地完成预定的工作。 + +##### 3) 隔离性 + +数据库允许多个并发事务同时对其数据进行读写和修改的能力,隔离性可以防止多个事务并发执行时由于交叉执行而导致数据的不一致。事务隔离分为不同级别,包括读未提交(Read uncommitted)、读提交(read committed)、可重复读(repeatable read)和串行化(Serializable)。 死锁 操作系统 + +##### 4) 持久性 + +事务处理结束后,对数据的修改就是永久的,即便系统故障也不会丢失。 + +## 事务的隔离级别 + +#### 事务的ACID属性 + +​ Atomicity 原子性:同一个事务中的操作,要么全部成功,要么全部失败。 + +​ Consistency 一致性:数据库中的数据保证合法,满足所有的约束(比如唯一约束) + +​ Isolation **隔离性**:不同的事务不能相互影响 + +​ Durability 持久性:事务提交后,不管数据库是否崩溃重启,提交的事务所作出的修改都要生效 + +如果不对事务进行隔离,多个事务同时发生在数据库中,将会导致以下的问题: + +- **脏读**:一个事务读取到另一个未提交事务的修改。没保证原子性,如果当前事务基于这些脏数据进行操作,另一个事务回滚后,这些操作将会是错误的 +- **不可重复读**:事务中,另外的事务提交了update或delete,导致当前事务前后读取到的数据不一致。没保证持久性,会导致当前事务覆盖另外事务的修改 +- **幻读**:事务中,另外的事务提交了insert,导致当前事务前后读取到的数据总量不一致。当前事务先对唯一约束进行检查发现没有与将要插入的数据重复的,此时另外的事务提交了,导致当前事务进行插入后数据库中有两条相同的数据,破环了一致性 + +#### 事务的四种隔离级别 + +**read-uncommitted** **读未提交** + +​ 可以读到未提交的数据(完全不隔离) + +**read-committed 读已提交** + +​ 只能读取已提交的数据(避免脏读) + +**repeatable-read 可重复读** + +​ 只能读取到事务开始前,其它事务提交的数据(避免脏读、不可重复读) + +**serializable 串行化** + +​ 所有事务一个一个执行,不进行并发(避免脏读、不可重复读、幻读) + +``` +--查看事务的隔离级别 +dbcc useroptions +--设置事务隔离级别 +set transaction isolation level <隔离级别> +``` + +# 2022.9.30 + +## 游标 + +游标(Cursor)它使用户可逐行访问由SQL Server返回的结果集。使用游标(cursor)的一个主要的原因就是把集合操作转换成**单个记录处理方式**。用SQL语言从数据库中检索数据后,结果放在内存的一块区域中,且结果往往是一个含有多个记录的集合。游标机制允许用户在SQL server内逐行地访问这些记录,按照用户自己的意愿来显示和处理这些记录。 + +游标分类: + +(1)静态游标(Static):在操作游标的时候,数据发生变化,游标中数据不变 +(2)动态游标(Dynamic):在操作游标的时候,数据发生变化,游标中数据改变,默认值。 +(3)键集驱动游标(KeySet):在操作游标的时候,被标识的列发生改变,游标中数据改变,其他列改变,游标中数据不变。 + +## 游标的使用 + +### 创建游标: + +```sql +--1.创建游标(Scroll代表滚动游标,不加Scroll则是只进的,只能支持fetch next) +declare <游标名> cursor scroll for select (表列名) from stuinfo +``` + +### 打开游标: + +```sql +open <游标名> +``` + +### 关闭游标: + +```sql +close <游标名> +``` + +### 释放游标: + +```sql +deallocate <游标名> +``` + +### 提取数据操作: + +```sql +fetch first from <游标名> --结果集的第一行 +fetch last from <游标名> --最后一行 +fetch absolute 1 from <游标名> --从游标的第一行开始数,第n行。 绝对 +fetch relative 3 from <游标名> --从当前位置数,第n行。 相对 +fetch next from <游标名> --当前位置的下一行 +fetch prior from <游标名> --当前位置的上一行 +``` + +## 游标题例 + +```sql +--声明游标 +--只进游标:游标中的数据只能往下查询,不能查之前的数据 +--滚动游标 (scroll):可以在任意时刻指向任意一行数据 +declare cur_UpdateSalaryById cursor scroll +for select PeopleId from People + +--先打开 +open cur_UpdateSalaryById + +--取数据 +declare @id int +declare @mon money =1000 +fetch first from cur_UpdateSalaryById into @id +while(@@FETCH_STATUS = 0) + begin + --扣钱 + update people set PeopleSalary -=@mon where PeopleId=@id + --打印 + print cast(@id as varchar(2) ) + char(9) + cast (@mon as varchar(10)) + set @mon += 1000 + --提取下一行 + fetch next from cur_UpdateSalaryById into @id + end + + --用完关闭 +close cur_UpdateSalaryById + + --释放 +deallocate cur_UpdateSalaryById +``` + + + +# 2022-10-06 + +## 自定义函数 + +两个函数的不同 + +```sql +1.标量值函数: 1.returns 数据类型 2.return 标量(某个值) + +2.多语句表值函数 1.returns 表名 table(字段 数据类型) 2.return +``` + +## 函数 + +函数分为(1)系统函数:,(2)自定义函数(方法:将一个功能封装成可重用的函数)。 + +其中自定义函数又可以分为(1)标量值函数(返回单个值),(2)表值函数(返回查询结果) + +本文主要介绍自定义函数的使用。 + +#### 标量值函数 + +语法结构: + +```sql +CREATE FUNCTION function_name(@parameter_name parameter_data_type) --(@参数名 参数的数据类型) +RETURNS date_type --返回返回值的数据类型 + +[AS] + +BEGIN + + function_body --函数体 + + RETURN 表达式; --必须要有的 + +END +``` + +定义函数要求实现: + +实现两个值的加和 + +使用函数求某门课的平均成绩 + +#### 表值函数 + +语法结构: + +```sql +create function 名称 + +([{@参数名称 参数类型[=默认值]}[,n]]) + +returns @局部变量 table(参数名 参数类型) + +[with encryption] + +[as] + +begin + +函数体 + +return 函数返回值 + +end +``` + +删除自定义函数 + +```sql +DROP function 函数名 +``` + +例题: + +```sql +--(1)编写一个函数求该银行的金额总和 +use BankTest +go +create function func_GetBankMoneyByAccId() +returns money +as +begin + declare @SumBankMoney money + select @SumBankMoney =(select sum(CardMoney ) from BankCard) + return @SumBankMoney +end +go + + +select dbo.func_GetBankMoneyByAccId() as 银行金额总和 + + +--(2)传入账户编号,返回账户真实姓名 +go +create function func_GetInfoByAcco_Id(@id int) +returns varchar(40) +as +begin + declare @name varchar(40) + select @name = (select RealName from AccountInfo where AccountId = @id) + return @name +end +go + +select dbo.func_GetInfoByAcco_Id( 2 ) as 姓名 + + +--(3)传递开始时间和结束时间,返回交易记录(存钱取钱),交易记录中包含 真实姓名,卡号,存钱金额,取钱金额,交易时间。 + +--方案一(逻辑复杂,函数内容除了返回结果的sql语句还有其他内容,例如定义变量等): + +go +create function func_GetCardExchangeByOpenTimeAndEndTime(@OpenTime smalldatetime,@EndTime smalldatetime) +returns @ExchangTable table( + Name varchar(30), + CardNo varchar(50), + MoneyInBank money, + MoneyOutBank money, + ExchangeTime smalldatetime +) +as +begin + insert into @ExchangTable + select A.RealName,CE.CardNo,CE.MoneyInBank,CE.MoneyOutBank,CE.ExchangeTime from CardExchange CE + join BankCard B on B.CardNo = CE.CardNo + join AccountInfo A on A.AccountId = B.AccountId + where A.OpenTime = @OpenTime and CE.ExchangeTime = @EndTime + return +end +go + +select * from func_GetCardExchangeByOpenTimeAndEndTime('2022-09-19 22:37:00','2022-09-19 22:37:00') +``` diff --git "a/12 \351\231\210\345\215\216\344\274\237/2022-10-06 \347\254\254\345\215\201\344\270\200\346\254\241\344\275\234\344\270\232\345\222\214\347\254\224\350\256\260/SQLQuery11.sql" "b/12 \351\231\210\345\215\216\344\274\237/2022-10-06 \347\254\254\345\215\201\344\270\200\346\254\241\344\275\234\344\270\232\345\222\214\347\254\224\350\256\260/SQLQuery11.sql" new file mode 100644 index 0000000..8f4fc4d --- /dev/null +++ "b/12 \351\231\210\345\215\216\344\274\237/2022-10-06 \347\254\254\345\215\201\344\270\200\346\254\241\344\275\234\344\270\232\345\222\214\347\254\224\350\256\260/SQLQuery11.sql" @@ -0,0 +1,162 @@ +use master + +use master + +select * from AccountInfo --个人信息 +select * from BankCard --银行卡信息 +select * from CardStateChange --银行卡状态更改表 +select * from CardTransfer --转账表 +select * from CardExchange --交易记录 +drop function func_SUMmoney +--(1)编写一个函数求该银行的金额总和 + create function func_SUMmoney() + returns money + as + begin + declare @sum money + select @sum= sum(CardMoney)from BankCard + return @sum + end + select dbo.func_SUMmoney() + +--(2)传入账户编号,返回账户真实姓名 + create function func_SUMname(@id int ) + returns varchar(20) + as + begin + declare @name varchar(20) + select @name= RealName from AccountInfo where AccountId = @id + return @name + end + + select dbo.func_SUMname(1) +--(3)传递开始时间和结束时间,返回交易记录(存钱取钱),交易记录中包含 真实姓名,卡号,存钱金额,取钱金额,交易时间。 + drop function GetRecordByTime + + create function GetRecordByTime(@start smalldatetime,@end smalldatetime) + returns @result table + ( + RealName varchar(30), + CardNo varchar(50), + MoneyInBank money, + MoneyOutBank money, + ExchangeTime smalldatetime + ) + as + begin + insert into @result + select RealName 姓名,CardExchange.CardNo 卡号,MoneyInBank 存钱金额,MoneyOutBank 取钱金额,ExchangeTime 交易时间 + from CardExchange + join BankCard on BankCard.CardNo=CardExchange.CardNo + join AccountInfo on AccountInfo.AccountId=BankCard.AccountId + where AccountInfo.OpenTime = @start and CardExchange.ExchangeTime = @end + + --where ExchangeTime between @start+'00:00:00' and @end+'23:59:59' + return + end + +select *from GetRecordByTime('2022-10-07 16:17:00','2022-10-07 16:17:00') + + + + +--方案一(逻辑复杂,函数内容除了返回结果的sql语句还有其他内容,例如定义变量等): + +--(4)查询银行卡信息,将银行卡状态1,2,3,4分别转换为汉字“正常,挂失,冻结,注销”,根据银行卡余额显示银行卡等级 30万以下为“普通用户”,30万及以上为"VIP用户",分别显示卡号,身份证,姓名,余额,用户等级,银行卡状态。 + +--方案一:直接在sql语句中使用case when + select BankCard.CardNo, AccountInfo.RealName ,AccountInfo.AccountCode , BankCard.CardMoney , + ( + case + when CardState = 1 then '正常' + when CardState = 2 then '挂失' + when CardState = 2 then '冻结' + else '注销' + end + ) as 状态, + ( + case when(BankCard.CardMoney<300000) then '普通用户' + else 'VIP用户' + end + ) as 银行卡等级 + from AccountInfo inner join BankCard on AccountInfo.AccountId = BankCard.AccountId + +--方案二:将等级和状态用函数实现 + go + create function fun_GetBankInfoByCardNo(@CardNo varchar(30)) + returns @BankInfo table( + CardNo varchar(30), + AccountCode varchar(30), + Name varchar(30), + CardMoney money, + UserLevel varchar(30), + BankCardStatus varchar(30) + ) + as + begin + insert into @BankInfo + select B.CardNo,AccountCode,RealName,CardMoney, + ( + case when CardMoney<300000 then '普通用户' + else 'VIP用户' + end + )UserLevel, + ( + case when CardState=1 then '正常' + when CardState=2 then '挂失' + when CardState=3 then '冻结' else '注销' + end + )BankCardStatus + from BankCard B + join AccountInfo A on A.AccountId = B.AccountId + where CardNo = @CardNo + return + end + go + + select * from fun_GetBankInfoByCardNo('6225547858741263') + + select * from AccountInfo + select * from CardExchange + select * from BankCard + +--(5)编写函数,根据出生日期求年龄,年龄求实岁,例如: + +​ --生日为2000-5-5,当前为2018-5-4,年龄为17岁 +​ --生日为2000-5-5,当前为2018-5-6,年龄为18岁 + +create table Emp +( + EmpId int primary key identity(1,2), --自动编号 + empName varchar(20), --姓名 + empSex varchar(4), --性别 + empBirth smalldatetime --生日 +) +insert into Emp(empName,empSex,empBirth) values('刘备','男','2008-5-8') +insert into Emp(empName,empSex,empBirth) values('关羽','男','1998-10-10') +insert into Emp(empName,empSex,empBirth) values('张飞','男','1999-7-5') +insert into Emp(empName,empSex,empBirth) values('赵云','男','2003-12-12') +insert into Emp(empName,empSex,empBirth) values('马超','男','2003-1-5') +insert into Emp(empName,empSex,empBirth) values('黄忠','男','1988-8-4') +insert into Emp(empName,empSex,empBirth) values('魏延','男','1998-5-2') +insert into Emp(empName,empSex,empBirth) values('简雍','男','1992-2-20') +insert into Emp(empName,empSex,empBirth) values('诸葛亮','男','1993-3-1') +insert into Emp(empName,empSex,empBirth) values('徐庶','男','1994-8-5') + +--看别人做的 +select * from Emp +go +create function fun_GetAge(@id int,@NowTime datetime) +returns int +as +begin + declare @BirthTime datetime + declare @age int + select @BirthTime = (select empBirth from Emp where EmpId = @id) + select @age = DATEDIFF(YY,@BirthTime,@NowTime) + select @age = case when DATEDIFF(DD,DATEADD(YY,@age,@BirthTime),@NowTime)<0 then @age-1 else @age end + return @age +end +go + +select dbo.fun_GetAgeByBirth(9,GETDATE()) as 年龄 \ No newline at end of file -- Gitee From 94c2810b0adf45175875be6504bab5aad3fd1b00 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=88=E5=8D=8E=E4=BC=9F?= <1931626338@qq.com> Date: Mon, 10 Oct 2022 11:19:50 +0800 Subject: [PATCH 2/2] =?UTF-8?q?=E5=AD=98=E5=82=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../2022-10-06 \345\255\230\345\202\250 .md" | 893 ++++++++++++++++++ .../SQLQuery12.sql" | 110 +++ 2 files changed, 1003 insertions(+) create mode 100644 "12 \351\231\210\345\215\216\344\274\237/2022-10-07 \347\254\254\345\215\201\344\272\214\346\254\241\344\275\234\344\270\232\345\222\214\347\254\224\350\256\260/2022-10-06 \345\255\230\345\202\250 .md" create mode 100644 "12 \351\231\210\345\215\216\344\274\237/2022-10-07 \347\254\254\345\215\201\344\272\214\346\254\241\344\275\234\344\270\232\345\222\214\347\254\224\350\256\260/SQLQuery12.sql" diff --git "a/12 \351\231\210\345\215\216\344\274\237/2022-10-07 \347\254\254\345\215\201\344\272\214\346\254\241\344\275\234\344\270\232\345\222\214\347\254\224\350\256\260/2022-10-06 \345\255\230\345\202\250 .md" "b/12 \351\231\210\345\215\216\344\274\237/2022-10-07 \347\254\254\345\215\201\344\272\214\346\254\241\344\275\234\344\270\232\345\222\214\347\254\224\350\256\260/2022-10-06 \345\255\230\345\202\250 .md" new file mode 100644 index 0000000..fbdd380 --- /dev/null +++ "b/12 \351\231\210\345\215\216\344\274\237/2022-10-07 \347\254\254\345\215\201\344\272\214\346\254\241\344\275\234\344\270\232\345\222\214\347\254\224\350\256\260/2022-10-06 \345\255\230\345\202\250 .md" @@ -0,0 +1,893 @@ +# 2022.9.16 + +## 创建数据库 + +```SQL +create database 数据库名 +``` + +## 创建数据表 + +```SQL +create table 表名( +) +``` + +## 查询数据 + +```sql +select * from 表名 +``` + +## 增删改查 + +```SQL +insert into 表名 ({字段1},{字段1},{字段1},....) values (值1,值1,值1,....) +alter table (表名) add (列名) varchar(255) ; +delete from 表名 where 删除条件 +drop table (表名) 删除整个表 +UPDATE 表名 SET 字段1=修改的值1,字段2=修改的值2,.. . .. WHERE 修改的条件 +``` + + + +## 主键,自增,不允许为空,默认值,外键,唯一约束 + +```sql +1.primary key 主键 +2.identity(1,1) 自增 初始ID,自增多少 +3.not null 不允许为空 +4.default('') 默认值 +5.userId(表名) int(字段) references(外键) userInfo(表名)(userNo)列名 外键 +6.unique 唯一约束 +``` + +# 2022.9.17 + +## SQL条件查询 + +```sql +=:等于,比较是否相等及赋值 +!=:比较不等于 +>:比较大于 +<:比较小于 +>=:比较大于等于 +<=:比较小于等于 +IS NULL:比较为空 +IS NOT NULL:比较不为空 +in:比较是否在其中 +like:模糊查询 +BETWEEN...AND...:比较是否在两者之间 50-100 BETWEEN 50 AND 100 +and:逻辑与(两个条件同时成立表达式成立) +or:逻辑或(两个条件有一个成立表达式成立) +not:逻辑非(条件成立,表达式则不成立;条件不成立,表达式则成立) +``` + +## 模糊查询 + +```sql +%:代表匹配0个字符、1个字符或多个字符。 +_:代表匹配有且只有1个字符。 +[]:代表匹配范围内 +[^]:代表匹配不在范围内 + +模糊查询,包含查询 +select * from 表名 where 列名 like '%要查询的字段%' + +模糊查询,开头查询 +select * from 表名 where 列名 like '要查询的字段%' + +模糊查询,结尾查询 +select * from 表名 where 列名 like '%要查询的字段' +``` + +## 聚合函数 + +```SQL +count:求数量 +max:求最大值 计算某一列的最大值 +min:求最小值 计算某一列的最小值 +sum:求和 计算某一列的合计值,该列必须为数值类型 +avg:求平均值 计算某一列的平均值,该列必须为数值类型 +``` + +## 升序降序查询 + +```SQL +-- desc 降序 默认升序 asc -- +SELECT * FROM 表名 order by 列名 desc +``` + + + +## ROUND函数用法: + +```SQL +round(num,len,[type]) +其中: +num表示需要处理的数字,len表示需要保留的长度,type处理类型(0是默认值代表四舍五入,非0代表直接截取) +select ROUND(123.45454,3) --123.45500 +select ROUND(123.45454,3,1) --123.45400 +``` + +## CONVERT()与CAST()函数: + +```SQL +--1.保留小数 +convert(decimal(13,2),12.45454) +cast(12.45454 as decimal(13,2)) +--2.强制转换类型 +``` + +## SQL中常用的时间函数 + +```SQL +select DATEDIFF(day, '2019-08-20', getDate()); --获取指定时间单位的差值 +SELECT DATEADD(MINUTE,-5,GETDATE()) --加减时间,此处为获取五分钟前的时间,MINUTE 表示分钟,可为 YEAR,MONTH,DAY,HOUR +select DATENAME(month, getDate()); --当前月份 +select DATENAME(WEEKDAY, getDate()); --当前星期几 +select DATEPART(month, getDate()); --当前月份 +select DAY(getDate()); --返回当前日期天数 +select MONTH(getDate()); --返回当前日期月数 +select YEAR(getDate()); --返回当前日期年数 + +SELECT CONVERT(VARCHAR(22),GETDATE(),20) --2020-01-09 14:46:46 +SELECT CONVERT(VARCHAR(24),GETDATE(),21) --2020-01-09 14:46:55.91 +SELECT CONVERT(VARCHAR(22),GETDATE(),23) --2020-01-09 +SELECT CONVERT(VARCHAR(22),GETDATE(),24) --15:04:07 +Select CONVERT(varchar(20),GETDATE(),14) --15:05:49:330 +``` + +## 连表查询 + +```SQL +内连接查询 +1.select * from 第一张表名 重命名字段1 +2.inner join 第二张表名 重命名字段2 on 重命名字段1.关联的列=重命名字段2.关联的列 +3.where 要筛选的条件、 + +左连接查询 +1.select * from 第一张表名 重命名字段1 +2.left join 第二张表名 重命名字段2 on 重命名字段1.关联的列=重命名字段2.关联的列 +3.where 要筛选的条件、 + +右连接查询 +1.select * from 第一张表名 重命名字段1 +2.right join 第二张表名 重命名字段2 on 重命名字段1.关联的列=重命名字段2.关联的列 +3.where 要筛选的条件、 +``` + +## **时间格式控制字符串:** + +| 名称 | 日期单位 | 缩写 | +| ------------ | ----------- | --------- | +| 年 | year | yyyy 或yy | +| 季度 | quarter | qq,q | +| 月 | month | mm,m | +| 一年中第几天 | dayofyear | dy,y | +| 日 | day | dd,d | +| 一年中第几周 | week | wk,ww | +| 星期 | weekday | dw | +| 小时 | Hour | hh | +| 分钟 | minute | mi,n | +| 秒 | second | ss,s | +| 毫秒 | millisecond | ms | + +## SQL语句执行顺序: + +```sql +(7) SELECT +(8) DISTINCT +(1) FROM +(3) JOIN +(2) ON +(4) WHERE +(5) GROUP BY +(6) HAVING +(9) ORDER BY +(10) LIMIT +``` + +# 2022.9.19 + +## 子查询 + +```sql +标量子查询:返回的是单行单列;标量子查询是指子查询返回的是**单一值**,如一个数字或一个字符串。 + +列子查询:返回的数据时1列n行,放在where之后 + +行子查询:是指子查询返回的结果集是1行N列,该子查询的结果通常是对表的某行数据进行查询而返回的结果集。 + +表子查询(from子查询) +表子查询是指子查询返回是M行N列的结果集,查询语句可嵌套在FROM关 +键字后,且需要定义别名。 +``` + +## all和any的区别 + +```sql +注意:1. =any 与in 等效. +all:是所有 +any:是任意一个 +any表示任何一个满足就返回TRUE,all表示全部都满足才返回TRUE +``` + +## 三个排序函数 + +```sql +row_number():连续,无并列 +dense_rank():有并列,不挑空 +rank():有并列,会挑空 + +--学生的Java成绩,并根据成绩排名 +--row_number() +select StuName 姓名,ROW_NUMBER() over(order by score desc) 排名,score 分数 from StuScore +join stuinfo on StuInfo.StuID = StuScore.StuID +where subject = 'Java' + +--rank() +select StuName 姓名,rank() over(order by score desc) 排名,score 分数 from StuScore +join stuinfo on StuInfo.StuID = StuScore.StuID +where subject = 'Java' + +--DENSE_RANK() + select StuName 姓名,dense_rank() over(order by score desc) 排名,score 分数 from StuScore +join stuinfo on StuInfo.StuID = StuScore.StuID +where subject = 'Java' +``` + +## exists子查询 + +关键字EXISTS构造子查询时,当子查询的结果集不为空时,则EXISTS返回的结果为TRUE,外层查询语句进行查询;当子查询的结果集为空时,则EXISTS返回的结果为FALSE,外层查询语句不进行查询。 + +```SQL + 关羽的银行卡号为"6225547858741263",查询当天是否有收到转账。 + if exists(select * from CardTransfer where CardNoIn = 6225547858741263) + print '有' + else + print '没有' +``` + +# 2022.9.21 + +## 关联子查询_排序 + +```SQL +row_number():连续,无并列 +dense_rank():有并列,不挑空 +rank():有并列,会挑空 +``` + +# 2022.9.22 + +## 变量 + +```sql +全局变量必须以标记@@作为前缀,如@@version +全局变量由**系统定义和维护**,我们**只能读取,不能修改全局变量的值** +全局变量在整个SQL环境下都可以被访问或调用 +--全局变量:只读,由系统定义和维护, @@ + +--@@ERROR:返回执行的上一个语句的错误号 +--@@IDENTITY:返回最后插入的标识值 +--@@MAX_CONNECTIONS:返回允许同时进行的最大用户连接数 +--@@ROWCOUNT:返回受上一语句影响的行数 +--@@SERVERNAME:返回运行 SQL Server 的本地服务器的名称 +--@@SERVICENAME:返回 SQL Server 正在其下运行的注册表项的名称 +--@@TRANCOUNT:返回当前连接的活动事务数 +--@@LOCK_TIMEOUT:返回当前会话的当前锁定超时设置(毫秒) +-------------------------------------------------------------------------------------- +局部变量必须以标记@作为前缀 ,如@age +局部变量的使用是先声明,再赋值 +局部变量只在定义它的局部范围内有效 + +声明一个局部变量:**declare @变量名 数据类型** +--局部变量: 声明(int a),赋值(a = 1) +--declare 变量名 数据类型 +例: + declare @id int --声明一个名为id的整型变量 + declare @name varchar(50) --声明一个可变长度为50的存放姓名的字符串变量 +``` + +# 赋值 + +赋值: + - set @变量名 = 值 + - select @变量名 = 值 + +```sql +--例: + select @id = 1001 + set @name = '周飘' +``` + +set与select赋值的区别: + +set赋值给变量指定的值,select一般用于表中查询出的数据赋值给变量,如果查询结果有多条,取最后一条赋值给变量 + +# 逻辑控制语句 + +## if条件分支 + +```sql +sql中的if-else语句 +if(条件) +begin +语句 +语句 +..... +end +else +begin +语句 +语句 +..... +end +``` + +## while 循环控制语句 + +while:可以通过break和continue控制循环语句中的执行。 + +break:跳出整个循环 + +continue:跳出当前循环 + +```sql +sql中的if-else语句 +while(条件) +begin +语句 +语句 +..... +end +``` + +## 逻辑控制语句 switch case + +``` + +``` + +# 批处理语句 + +go语句特点: + +1. 等待go语句前的代码执行完成后,再执行go后面的代码。 +2. 批处理语句的结束标志。 + +```sql +--下面的@num变量作用域为全局 +--declare @num int +--set @num = 0 + +--下面的@num变量的作用域是局部,只在两个go之间可以使用,最后一行代码会报错 +--.........sql代码 +--go +--declare @num int +--set @num = 0 +--go +--set @num = 1 +``` + +# 2022-9-26 + +## 视图 + +三种类型关系: + +- 表(Table)--基表,存储关系(Base Tables,Sorted relations) +- 视图(Views)--虚拟表,虚拟关系(Virtual relations)(不是物理存在的是虚拟的) +- 临时结果--临时表,(select * from, Temporary results)--用于构建**子查询**的结果 + +with check option --涉及的增删只能对信息学院的学生进行操作 + +## 定义视图 + +```sql +--1.建立视图 +create view <视图名> [(<列名>[,<列名>]...)] +as <子查询> [with check option] + + +create view V_GetInfo(虚拟表) +as +select stu_num(列名), name(列名), school(列名) from tb_student(表名) +select * from V_GetInfo + +--2.使用 +--视图是一张虚拟表 +select * from V_GetInfo --》视图转化: select stu_num, name, school from tb_student + +--3.删除(虚拟表) +--drop view V_GetInfo + +--4.建立信息学院学生的视图 使用,查询虚拟表 +create view V_Info +as +select * from tb_student where school='信息学院' +with check option --涉及的增删只能对信息学院的学生进行操作 + +--5.分组视图:使用group by 建立视图 +create view V_GetTotalPrize(生源地,荣誉总数) +as +select ori_loca , sum(prize) from tb_inf_student group by ori_loca +select * from V_GetTotalPrize + +--6.定义一个反映学生年龄的视图 +create view V_GetAgeByBirth(学号,姓名,年龄) +as +select stu_num,name, (year(getdate()) - year(birth)) from tb_student +select * from V_GetAgeByBirth + +--7.建立信息学院学生的特长属于艺术特长视图 连表查询 +create view V_GetSpecBySch +as +select tb_student.*,hobby,speciality,ori_loca,prize from tb_student join tb_inf_student on tb_student.stu_num = tb_inf_student.stu_num where school='信息学院' and speciality='艺术特长' + +--8.基于视图的视图:视图可作为另一视图建立的表 +create view V_GetOriInBJ +as +select * from V_GetSpecBySch where ori_loca = '北京' +select * from V_GetOriInBJ +``` + +## 查询视图 + +更新视图:不推荐直接在视图进行更新操作,增,删 操作 + +视图一般只用来查询,如果是单表的话,也可以进行增删改。但是有如下限制。 + 1.聚合函数(SUM(), MIN(), MAX(), COUNT()等)。 + +2. DISTINCT + +3. GROUP BY +4. 4 HAVING +5. UNION或UNION ALL (连表) +6. 位于选择列表中的子查询 + 7.Join + 8.FROM子句中的不可更新视图 +7. WHERE子句中的子查询,引用FROM子句中的表。 +8. 仅引用文字值(在该情况下,没有要更新的基本表)。 +9. ALGORITHM = TEMPTABLE(使用临时表总会使视图成为不可更新的)。 + +##### 删除视图 + +```sql +drop view <视图名> +--该语句从数据字典中删除指定的视图定义 +--由该视图导出的其他视图仍在数据字典中,但不能使用,需要删除 +--删除基表时,由该基表导出的所有视图定义都必须显示删除 +``` + +# 2022-9-27到29 + +## 事务 + +**事务( Transaction)由一次或者多次基本操作构成,或者说,事务由一条或者多条 SQL 语句构成。** + +**事务中的所有 SQL 语句是一个整体,共同进退,不可分割,要么全部执行成功,要么全部执行失败。** + +## 事务的属性(ACID) + +一般来说,事务具有四个标准属性,分别是原子性(**A**tomicity,或称不可分割性)、一致性(**C**onsistency)、隔离性(**I**solation,又称独立性)、持久性(**D**urability),简称 **ACID**。具体说明如下: + +##### 1) 原子性 + +一个事务中的所有 SQL 语句,要么全部执行成功,要么全部执行失败,不会结束在中间的某个环节。事务在执行过程中发生错误,会被回滚(Rollback)到事务开始前的状态,就像这个事务从来没有执行过一样。 + +##### 2) 一致性 + +在事务开始之前和事务结束以后,数据库的完整性没有被破坏。这表示写入的数据必须完全符合所有的预设规则,其中包含数据的精确度、串联性以及后续数据库可以自发性地完成预定的工作。 + +##### 3) 隔离性 + +数据库允许多个并发事务同时对其数据进行读写和修改的能力,隔离性可以防止多个事务并发执行时由于交叉执行而导致数据的不一致。事务隔离分为不同级别,包括读未提交(Read uncommitted)、读提交(read committed)、可重复读(repeatable read)和串行化(Serializable)。 死锁 操作系统 + +##### 4) 持久性 + +事务处理结束后,对数据的修改就是永久的,即便系统故障也不会丢失。 + +## 事务的隔离级别 + +#### 事务的ACID属性 + +​ Atomicity 原子性:同一个事务中的操作,要么全部成功,要么全部失败。 + +​ Consistency 一致性:数据库中的数据保证合法,满足所有的约束(比如唯一约束) + +​ Isolation **隔离性**:不同的事务不能相互影响 + +​ Durability 持久性:事务提交后,不管数据库是否崩溃重启,提交的事务所作出的修改都要生效 + +如果不对事务进行隔离,多个事务同时发生在数据库中,将会导致以下的问题: + +- **脏读**:一个事务读取到另一个未提交事务的修改。没保证原子性,如果当前事务基于这些脏数据进行操作,另一个事务回滚后,这些操作将会是错误的 +- **不可重复读**:事务中,另外的事务提交了update或delete,导致当前事务前后读取到的数据不一致。没保证持久性,会导致当前事务覆盖另外事务的修改 +- **幻读**:事务中,另外的事务提交了insert,导致当前事务前后读取到的数据总量不一致。当前事务先对唯一约束进行检查发现没有与将要插入的数据重复的,此时另外的事务提交了,导致当前事务进行插入后数据库中有两条相同的数据,破环了一致性 + +#### 事务的四种隔离级别 + +**read-uncommitted** **读未提交** + +​ 可以读到未提交的数据(完全不隔离) + +**read-committed 读已提交** + +​ 只能读取已提交的数据(避免脏读) + +**repeatable-read 可重复读** + +​ 只能读取到事务开始前,其它事务提交的数据(避免脏读、不可重复读) + +**serializable 串行化** + +​ 所有事务一个一个执行,不进行并发(避免脏读、不可重复读、幻读) + +``` +--查看事务的隔离级别 +dbcc useroptions +--设置事务隔离级别 +set transaction isolation level <隔离级别> +``` + +# 2022.9.30 + +## 游标 + +游标(Cursor)它使用户可逐行访问由SQL Server返回的结果集。使用游标(cursor)的一个主要的原因就是把集合操作转换成**单个记录处理方式**。用SQL语言从数据库中检索数据后,结果放在内存的一块区域中,且结果往往是一个含有多个记录的集合。游标机制允许用户在SQL server内逐行地访问这些记录,按照用户自己的意愿来显示和处理这些记录。 + +游标分类: + +(1)静态游标(Static):在操作游标的时候,数据发生变化,游标中数据不变 +(2)动态游标(Dynamic):在操作游标的时候,数据发生变化,游标中数据改变,默认值。 +(3)键集驱动游标(KeySet):在操作游标的时候,被标识的列发生改变,游标中数据改变,其他列改变,游标中数据不变。 + +## 游标的使用 + +### 创建游标: + +```sql +--1.创建游标(Scroll代表滚动游标,不加Scroll则是只进的,只能支持fetch next) +declare <游标名> cursor scroll for select (表列名) from stuinfo +``` + +### 打开游标: + +```sql +open <游标名> +``` + +### 关闭游标: + +```sql +close <游标名> +``` + +### 释放游标: + +```sql +deallocate <游标名> +``` + +### 提取数据操作: + +```sql +fetch first from <游标名> --结果集的第一行 +fetch last from <游标名> --最后一行 +fetch absolute 1 from <游标名> --从游标的第一行开始数,第n行。 绝对 +fetch relative 3 from <游标名> --从当前位置数,第n行。 相对 +fetch next from <游标名> --当前位置的下一行 +fetch prior from <游标名> --当前位置的上一行 +``` + +## 游标题例 + +```sql +--声明游标 +--只进游标:游标中的数据只能往下查询,不能查之前的数据 +--滚动游标 (scroll):可以在任意时刻指向任意一行数据 +declare cur_UpdateSalaryById cursor scroll +for select PeopleId from People + +--先打开 +open cur_UpdateSalaryById + +--取数据 +declare @id int +declare @mon money =1000 +fetch first from cur_UpdateSalaryById into @id +while(@@FETCH_STATUS = 0) + begin + --扣钱 + update people set PeopleSalary -=@mon where PeopleId=@id + --打印 + print cast(@id as varchar(2) ) + char(9) + cast (@mon as varchar(10)) + set @mon += 1000 + --提取下一行 + fetch next from cur_UpdateSalaryById into @id + end + + --用完关闭 +close cur_UpdateSalaryById + + --释放 +deallocate cur_UpdateSalaryById +``` + + + +# 2022-10-05 + +## 自定义函数 + +两个函数的不同 + +```sql +1.标量值函数: 1.returns 数据类型 2.return 标量(某个值) + +2.多语句表值函数 1.returns 表名 table(字段 数据类型) 2.return +``` + +## 函数 + +函数分为(1)系统函数:,(2)自定义函数(方法:将一个功能封装成可重用的函数)。 + +其中自定义函数又可以分为(1)标量值函数(返回单个值),(2)表值函数(返回查询结果) + +本文主要介绍自定义函数的使用。 + +#### 标量值函数 + +语法结构: + +```sql +CREATE FUNCTION function_name(@parameter_name parameter_data_type) --(@参数名 参数的数据类型) +RETURNS date_type --返回返回值的数据类型 + +[AS] + +BEGIN + + function_body --函数体 + + RETURN 表达式; --必须要有的 + +END +``` + +定义函数要求实现: + +实现两个值的加和 + +使用函数求某门课的平均成绩 + +#### 表值函数 + +语法结构: + +```sql +create function 名称 + +([{@参数名称 参数类型[=默认值]}[,n]]) + +returns @局部变量 table(参数名 参数类型) + +[with encryption] + +[as] + +begin + +函数体 + +return 函数返回值 + +end +``` + +删除自定义函数 + +```sql +DROP function 函数名 +``` + +例题: + +```sql +--(1)编写一个函数求该银行的金额总和 +use BankTest +go +create function func_GetBankMoneyByAccId() +returns money +as +begin + declare @SumBankMoney money + select @SumBankMoney =(select sum(CardMoney ) from BankCard) + return @SumBankMoney +end +go + + +select dbo.func_GetBankMoneyByAccId() as 银行金额总和 + + +--(2)传入账户编号,返回账户真实姓名 +go +create function func_GetInfoByAcco_Id(@id int) +returns varchar(40) +as +begin + declare @name varchar(40) + select @name = (select RealName from AccountInfo where AccountId = @id) + return @name +end +go + +select dbo.func_GetInfoByAcco_Id( 2 ) as 姓名 + + +--(3)传递开始时间和结束时间,返回交易记录(存钱取钱),交易记录中包含 真实姓名,卡号,存钱金额,取钱金额,交易时间。 + +--方案一(逻辑复杂,函数内容除了返回结果的sql语句还有其他内容,例如定义变量等): + +go +create function func_GetCardExchangeByOpenTimeAndEndTime(@OpenTime smalldatetime,@EndTime smalldatetime) +returns @ExchangTable table( + Name varchar(30), + CardNo varchar(50), + MoneyInBank money, + MoneyOutBank money, + ExchangeTime smalldatetime +) +as +begin + insert into @ExchangTable + select A.RealName,CE.CardNo,CE.MoneyInBank,CE.MoneyOutBank,CE.ExchangeTime from CardExchange CE + join BankCard B on B.CardNo = CE.CardNo + join AccountInfo A on A.AccountId = B.AccountId + where A.OpenTime = @OpenTime and CE.ExchangeTime = @EndTime + return +end +go + +select * from func_GetCardExchangeByOpenTimeAndEndTime('2022-09-19 22:37:00','2022-09-19 22:37:00') +``` + +# 2022.10.06 + +## 存储 + +## 存储过程(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.函数可以作为条件在语句中使用,但是存储过程不可以。 + diff --git "a/12 \351\231\210\345\215\216\344\274\237/2022-10-07 \347\254\254\345\215\201\344\272\214\346\254\241\344\275\234\344\270\232\345\222\214\347\254\224\350\256\260/SQLQuery12.sql" "b/12 \351\231\210\345\215\216\344\274\237/2022-10-07 \347\254\254\345\215\201\344\272\214\346\254\241\344\275\234\344\270\232\345\222\214\347\254\224\350\256\260/SQLQuery12.sql" new file mode 100644 index 0000000..4781b78 --- /dev/null +++ "b/12 \351\231\210\345\215\216\344\274\237/2022-10-07 \347\254\254\345\215\201\344\272\214\346\254\241\344\275\234\344\270\232\345\222\214\347\254\224\350\256\260/SQLQuery12.sql" @@ -0,0 +1,110 @@ +--1. 洢ʵֲѯ˻͵п˻Ϣ,ʾпţ˻ +--2. ģпǮпţǮʵִǮ +--3. ģпȡǮпţȡǮʵȡǮȡǮɹ1ȡǮʧܷ-1 +--4. **ѯijʱεдȡϢԼܽ**ȡܽ뿪ʼʱ䣬ʱ䣬ʾȡϢͬʱشܽȡܽ +--5. ****û룬ûȷ볤<8Զ8λ +--(ʾ 0-9 float(rand()*10)) rand():0.0-1.0С float:ȡ +use master + +select * from [dbo].[AccountInfo] +select * from [dbo].[BankCard] +select * from [dbo].[CardExchange] +select * from [dbo].[CardStateChange] +select * from [dbo].[CardTransfer] +--1. 洢ʵֲѯ˻͵п˻Ϣ,ʾпţ˻ + --ûûĴ洢 + drop procedure process_Inmoeny + create proc process_Inmoeny + as + begin + select BankCard.CardNo, AccountInfo.RealName ,BankCard.CardMoney from BankCard + inner join AccountInfo on BankCard.AccountId=AccountInfo.AccountId + where BankCard.CardMoney =(select min(CardMoney) from BankCard) + end + exec process_Inmoeny + + --2. ģпǮпţǮʵִǮ + --ûĴ洢 + drop procedure proc_INmoney + + create proc proc_INmoney + @cardno varchar(20), + @money money + as + begin + update BankCard set CardMoney = CardMoney + @money + where CardNo= @cardno + insert into CardExchange (CardNo,MoneyInBank,MoneyOutBank,ExchangeTime) + values (@cardno,@money,0,getdate()) + end + exec proc_INmoney 6225125478544587,1000 + + --3. ģпȡǮпţȡǮʵȡǮȡǮɹ1ȡǮʧܷ-1 + --ûĴ洢 + drop procedure proc_outmoney + + create proc proc_outmoney + @cardno varchar(20), + @money money + as + begin + update BankCard set CardMoney = CardMoney - @money + where CardNo= @cardno + if (@@error!=0) + return -1 + insert into CardExchange (CardNo,MoneyInBank,MoneyOutBank,ExchangeTime) + values (@cardno,@money,0,getdate()) + return 1 + end + + exec proc_INmoney 6225125478544587,1000 + +--4. **ѯijʱεдȡϢԼܽ**ȡܽ뿪ʼʱ䣬ʱ䣬ʾȡϢͬʱشܽȡܽ + --Ĵ洢 + --ģԼ + drop procedure proc_time + + create proc proc_time + @start smalldatetime, + @end smalldatetime, + @InSum money output, + @OutSum money output + as + begin + select @InSum = SUM(MoneyInBank),@OutSum = SUM(MoneyOutBank) from CardExchange + where ExchangeTime between @start and @end + end + go + + declare @start smalldatetime = '2022-09-07 14:30:00', + @end smalldatetime = '2022-09-27 08:19:00', + @InSum money,@OutSum money + + exec proc_time @start,@end,@InSum output,@OutSum output + select @InSum ܶ,@OutSum ȡܶ + + --5. ****û룬ûȷ볤<8Զ8λ + --һǿţֻ빦ܣһ룬빦ܣҲܡ + --˵ҵ + create proc pro_pwd + @carNo varchar(50), + @pwd varchar(50) +as +begin + if((select CardNo from BankCard where CardNo =@carNo) !='' + and @pwd = (select CardPwd from BankCard where CardNo =@carNo and @pwd=CardPwd )) + begin + if(len(@pwd) <8) + begin + update BankCard set CardPwd = CONCAT(ROUND(99999+RAND()*99999,0),ROUND(RAND()*9,0),ROUND(RAND()*9,0)) where CardNo =@carNo + end + end + else + begin + print'' + end + end + go + declare @carNo varchar(50) = '6225547854125656',@pwd varchar(50) = '123456' + exec pro_pwd @carNo,@pwd + select * from BankCard \ No newline at end of file -- Gitee