From e696bb3b1905ff4d79e5f6cbf98e41f733ee184e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=90=B4=E8=B6=85?= <9828390+wu-chao24@user.noreply.gitee.com> Date: Mon, 26 Sep 2022 14:17:13 +0000 Subject: [PATCH 1/2] =?UTF-8?q?=E4=BD=9C=E4=B8=9A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: 吴超 <9828390+wu-chao24@user.noreply.gitee.com> --- ...70\346\240\207\344\275\234\344\270\232.md" | 38 ++++++++++++++++ ...75\346\225\260\344\275\234\344\270\232.md" | 44 +++++++++++++++++++ 2 files changed, 82 insertions(+) create mode 100644 "30\345\220\264\350\266\205/\344\275\234\344\270\232/9.20\346\270\270\346\240\207\344\275\234\344\270\232.md" create mode 100644 "30\345\220\264\350\266\205/\344\275\234\344\270\232/9.21\345\207\275\346\225\260\344\275\234\344\270\232.md" diff --git "a/30\345\220\264\350\266\205/\344\275\234\344\270\232/9.20\346\270\270\346\240\207\344\275\234\344\270\232.md" "b/30\345\220\264\350\266\205/\344\275\234\344\270\232/9.20\346\270\270\346\240\207\344\275\234\344\270\232.md" new file mode 100644 index 0000000..25ac24e --- /dev/null +++ "b/30\345\220\264\350\266\205/\344\275\234\344\270\232/9.20\346\270\270\346\240\207\344\275\234\344\270\232.md" @@ -0,0 +1,38 @@ +``` +--- 创建学生游标,该游标包含(学生姓名,兴趣爱好,生源地,荣誉总数) +declare xsyb cursor scroll for (select name,hobby,ori_loca,prize from tb_inf_student join tb_student on tb_student.stu_num=tb_inf_student.stu_num ) +open xsyb +close xsyb + +--- 循环遍历161开头的学生信息 +declare xsx cursor scroll for(select * from tb_student where stu_num like'161%') +open xsx +declare @a varchar(20) +declare @a1 varchar(20) +declare @a2 varchar(20) +declare @a3 varchar(20) +declare @a4 varchar(20) +declare @a5 varchar(20) +--fetch first from xsx +fetch first from xsx into @a,@a1,@a2,@a3,@a4,@a5 +while @@FETCH_STATUS=0 +begin + print @a+''+@a1+' '+@a2+' '+@a3+' '+@a4+' '+@a5 + fetch next from xsx into @a,@a1,@a2,@a3,@a4,@a5 +end + close xsxx +--- 使用游标统计生源地为北京的荣誉总数 +declare zsss cursor scroll for (select prize from tb_inf_student where ori_loca='北京') +open zsss +declare @bb int =0 +declare @cc int +fetch first from zsss into @cc + +while @@FETCH_STATUS=0 +begin + set @bb=@bb+@cc + fetch next from zsss into @cc + +end +print @bb +``` \ No newline at end of file diff --git "a/30\345\220\264\350\266\205/\344\275\234\344\270\232/9.21\345\207\275\346\225\260\344\275\234\344\270\232.md" "b/30\345\220\264\350\266\205/\344\275\234\344\270\232/9.21\345\207\275\346\225\260\344\275\234\344\270\232.md" new file mode 100644 index 0000000..c84867e --- /dev/null +++ "b/30\345\220\264\350\266\205/\344\275\234\344\270\232/9.21\345\207\275\346\225\260\344\275\234\344\270\232.md" @@ -0,0 +1,44 @@ +``` +--(1)编写一个函数求该银行的金额总和 +go +create function banktotal() +returns decimal +as +begin + declare @sum decimal = (select sum(cardmoney) from BankCard) + return @sum +end +go +select dbo.banktotal() 金额总和 + + +--(2)传入账户编号,返回账户真实姓名 +go +create function Bankid(@id int) +returns varchar(5) +as +begin + declare @name varchar(5) = (select RealName from BankCard b join AccountInfo a on b.AccountId = a.AccountId where b.AccountId = @id) + return @name +end +go + +select dbo.Bankid(3)账户姓名 + +--(3)传递开始时间和结束时间,返回交易记录(存钱取钱),交易记录中包含 真实姓名,卡号,存钱金额,取钱金额,交易时间。 +DROP function Exchange +go +create function Exchange(@start smalldatetime,@end smalldatetime) +returns @tableinfo table(Realname varchar(10),cardno varchar(20),MoneyInBank decimal,MoneyOutBank decimal,ExchangeTime date) +as +begin + insert into @tableinfo + select RealName,c.CardNo,MoneyInBank,MoneyOutBank,ExchangeTime from BankCard b join AccountInfo a on b.AccountId = a.AccountId join CardExchange c on b.CardNo = c.CardNo + where ExchangeTime between @start and @end + return +end +go + +select * from dbo.Exchange('2022-07-1','2022-09-30') + +``` \ No newline at end of file -- Gitee From caa723c73ddbd5f001e02509cca646d451f8aaf4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=90=B4=E8=B6=85?= <9828390+wu-chao24@user.noreply.gitee.com> Date: Mon, 26 Sep 2022 14:17:51 +0000 Subject: [PATCH 2/2] =?UTF-8?q?=E7=AC=94=E8=AE=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: 吴超 <9828390+wu-chao24@user.noreply.gitee.com> --- ...13\345\212\241\347\254\224\350\256\260.md" | 43 +++++++ ...70\346\240\207\347\254\224\350\256\260.md" | 109 +++++++++++++++++ ...75\346\225\260\347\254\224\350\256\260.md" | 111 ++++++++++++++++++ ...73\351\224\201\347\254\224\350\256\260.md" | 41 +++++++ ...07\347\250\213\347\254\224\350\256\260.md" | 50 ++++++++ 5 files changed, 354 insertions(+) create mode 100644 "30\345\220\264\350\266\205/\347\254\224\350\256\260/9.19\344\272\213\345\212\241\347\254\224\350\256\260.md" create mode 100644 "30\345\220\264\350\266\205/\347\254\224\350\256\260/9.20\346\270\270\346\240\207\347\254\224\350\256\260.md" create mode 100644 "30\345\220\264\350\266\205/\347\254\224\350\256\260/9.21\345\207\275\346\225\260\347\254\224\350\256\260.md" create mode 100644 "30\345\220\264\350\266\205/\347\254\224\350\256\260/9.22\346\255\273\351\224\201\347\254\224\350\256\260.md" create mode 100644 "30\345\220\264\350\266\205/\347\254\224\350\256\260/9.26\345\255\230\345\202\250\350\277\207\347\250\213\347\254\224\350\256\260.md" diff --git "a/30\345\220\264\350\266\205/\347\254\224\350\256\260/9.19\344\272\213\345\212\241\347\254\224\350\256\260.md" "b/30\345\220\264\350\266\205/\347\254\224\350\256\260/9.19\344\272\213\345\212\241\347\254\224\350\256\260.md" new file mode 100644 index 0000000..394dc6f --- /dev/null +++ "b/30\345\220\264\350\266\205/\347\254\224\350\256\260/9.19\344\272\213\345\212\241\347\254\224\350\256\260.md" @@ -0,0 +1,43 @@ +## 事务 + +**事务( 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 持久性 + +事务处理结束后,对数据的修改就是永久的,即便系统故障也不会丢失。 + +### 事务的流程 + +1. ##### 开始事务:BEGIN TRANSACTION + + 事务开始后,直接执行代码,通常在修改表的代码行后会插入全局变量(@ERROR)进行错误代码的判断,一般会定义变量来装错误代码(@ERROR),在执行代码后,会用if进行判断 + + @ERROR是否为0,若为0则提交事务,反之回滚 + +2. ##### 提交事务:COMMIT TRANSACTION + + 当代码块无错误时,直接执行代码块 + +3. ##### 回滚事务:ROLLBACK TRANSACTION + + 当代码块有错误时,返回以上至begin之间已执行的代码。 + +4. ##### 存储点语句:SAVE TRANSACTION \ No newline at end of file diff --git "a/30\345\220\264\350\266\205/\347\254\224\350\256\260/9.20\346\270\270\346\240\207\347\254\224\350\256\260.md" "b/30\345\220\264\350\266\205/\347\254\224\350\256\260/9.20\346\270\270\346\240\207\347\254\224\350\256\260.md" new file mode 100644 index 0000000..5e7d67d --- /dev/null +++ "b/30\345\220\264\350\266\205/\347\254\224\350\256\260/9.20\346\270\270\346\240\207\347\254\224\350\256\260.md" @@ -0,0 +1,109 @@ +## 游标 + +游标(Cursor)它使用户可逐行访问由SQL Server返回的结果集。使用游标(cursor)的一个主要的原因就是把集合操作转换成单个记录处理方式。用SQL语言从数据库中检索数据后,结果放在内存的一块区域中,且结果往往是一个含有多个记录的集合。游标机制允许用户在SQL server内逐行地访问这些记录,按照用户自己的意愿来显示和处理这些记录。 + +**优点** + +从游标定义可以得到游标的如下优点,这些优点使游标在实际应用中发挥了重要作用: + +1 允许程序对由查询语句select返回的行集合中的每一行执行相同或不同的操作,而不是对整个行集合执行同一个操作。 + +2 提供对基于游标位置的表中的行进行删除和更新的能力。 + +3 游标实际上作为面向集合的数据库管理系统(RDBMS)和面向行的程序设计之间的桥梁,使这两种处理方式通过游标沟通起来。 + +游标的使用 + +讲了这个多游标的优点,现在我们就亲自来揭开游标的神秘的面纱。 + +使用游标的顺序: 声名游标、打开游标、读取数据、关闭游标、删除游标。 + +声明游标 + +最简单游标声明:DECLARE <游标名>CURSOR FOR; + +其中select语句可以是简单查询,也可以是复杂的接连查询和嵌套查询 + +  表明MS SQL SERVER 会将游标定义所选取出来的数据记录存放在一临时表内(建立在tempdb 数据库下)。对该游标的读取操作皆由临时表来应答。因此,对基本表的修改并不影响游标提取的数据,即游标不会随着基本表内容的改变而改变,同时也无法通过游标来更新基本表。如果不使用该保留字,那么对基本表的更新、删除都会反映到游标中。 + +另外应该指出,当遇到以下情况发生时,游标将自动设定INSENSITIVE 选项。 + +a.在SELECT 语句中使用DISTINCT、 GROUP BY、 HAVING UNION 语句; + +b.使用OUTER JOIN; + +c.所选取的任意表没有索引; + +d.将实数值当作选取的列。 + +SCROLL + +表明所有的提取操作(如FIRST、 LAST、 PRIOR、 NEXT、 RELATIVE、 ABSOLUTE)都可用。如果不使用该保留字,那么只能进行NEXT 提取操作。由此可见,SCROLL 极大地增加了提取数据的灵活性,可以随意读取结果集中的任一行数据记录,而不必关闭再重开游标。 + +**打开游标** + +非常简单,我们就打开刚才我们声明的游标mycursor + +OPEN mycursor + +**读取数据** + +FETCH [ NEXT | PRIOR | FIRST | LAST] FROM { 游标名 | @游标变量名 } [ INTO @变量名 [,…] ] + +参数说明: + +NEXT 取下一行的数据,并把下一行作为当前行(递增)。由于打开游标后,行指针是指向该游标第1行之前,所以第一次执行FETCH NEXT操作将取得游标集中的第1行数据。NEXT为默认的游标提取选项。 + +  INTO @变量名[,…] 把提取操作的列数据放到局部变量中。列表中的各个变量从左到右与游标结果集中的相应列相关联。各变量的数据类型必须与相应的结果列的数据类型匹配或是结果列数据类型所支持的隐性转换。变量的数目必须与游标选择列表中的列的数目一致。 + +**删除游标** + +DEALLOCATE mycursor + +**实例训练** + +如上我介绍完了游标使用的5个步骤,那现在我们就来上上手,练习用游标取出表2 AddSalary的数据。 + +为了运行我们自己创建的游标,我们将游标写在存储过程里,方便我们看到游标的整个使用过程。 + +附:游标使用方法使用游标必须经历五个步骤: + +①定义游标:delare + +②打开游标:open + +③逐行提取游标集中的行:fetch + +④关闭游标:close + +⑤释放游标:Deallocate + +1、语法: + +1 ①declare cursor_name cursor for SQL查询 + +2 [for [read only|update {of column-name list}] + +3 缺省update + +4 ②open curser_name + +5 ③fetch curser_name [into 变量表] + +6 当游标移至尾部,不可以再读取游标,必须关闭游标然后重新打开游标。 + +7 可以通过检查全局变量@@fetch_status来判断是否已读完游标集中所有行。 + +8 ④Close curser_name + +9 ⑤Deallocate curser_name. + +2、删除游标集中当前行 + +Delete from 表名 where current of curser_name + +从游标中删除一行后,游标定位于被删除的游标之后的一行,必须再用fetch得到该行。 + +3、更新游标集中当前行 + +update 表名 set 列名=表达式 [,列名=表达式] where current of curser_name \ No newline at end of file diff --git "a/30\345\220\264\350\266\205/\347\254\224\350\256\260/9.21\345\207\275\346\225\260\347\254\224\350\256\260.md" "b/30\345\220\264\350\266\205/\347\254\224\350\256\260/9.21\345\207\275\346\225\260\347\254\224\350\256\260.md" new file mode 100644 index 0000000..e73007a --- /dev/null +++ "b/30\345\220\264\350\266\205/\347\254\224\350\256\260/9.21\345\207\275\346\225\260\347\254\224\350\256\260.md" @@ -0,0 +1,111 @@ +# 函数 + +函数分为 + +- (1)系统函数: +- (2)自定义函数(方法:将一个功能封装成可重用的函数)。 + +其中自定义函数又可以分为 + +- (1)标量值函数(返回单个值) +- (2)表值函数(返回查询结果) + +区别 + +- 表值函数返回的是一张表结果,就和一个select查询语句一样,只不过里面带入了参数 +- 标量值函数返回的只是一个值 + +### 一、表值函数又分为内联函数与多语句函数 + +##### (1)内联函数就是没有函数主体是单个select + +``` +不带输入参数的表值函数 +create function tvpoints() +returns table +as +return +( +select * from tb_users +); +``` + +select * from tvpoints()这个结果返回的是一个表 + +##### (2)带参的内联表值函数 + +``` +对于多语句表值函数,在Begin...End语句块中定义的函数体包含一系列Transact-SQL语句,这些语句可生成行并将其插入将返回的表中. +create function tvpoints() +returns @points table (x float,y float) +as begin +insert @points values(1,2); +insert @points values(3,4); +returns; +end +``` + +select * from tvpoints2(x,y)查询到的是一张表 + +##### (3)标量函数(返回一个具体类型的值而不是一张表) + +``` +create function FUN_DataFormat(@strDate datetime) +Returns varchar(20) as +begin + declare @date varchar(20) + set @date=Datename(YY,@strDate)+'年'+Convert(varchar,month(@strDate))+'月'+Convert(Varchar,Day(@strDate))+'日' + return @date + end +``` + +可以通过select abo.fun_DataFormat(getdate())来使用.(用的时候一定要在函数前面添加一个dbo或者的话数据库语句报错的会提示不认识的) + +##### 删除自定义函数 + +``` +DROP function 函数名 +``` + +# 语法结构 + +#### 标量值函数 + +``` +CREATE FUNCTION function_name(@parameter_name parameter_data_type) --(@参数名 参数的数据类型) +RETURNS date_type --返回返回值的数据类型 + +[WITH ENCRYPTION] --如果指定了 encryption 则函数被加密 + +[AS] + +BEGIN + + function_body --函数体 + + RETURN 表达式; + +END +``` + +#### 表值函数 + +``` +create function 名称 + +([{@参数名称 参数类型[=默认值]}[,n]]) + +returns @局部变量 table(参数名 参数类型) + +[with encryption] + +[as] + +begin + +函数体 + +return 函数返回值 + +end +``` \ No newline at end of file diff --git "a/30\345\220\264\350\266\205/\347\254\224\350\256\260/9.22\346\255\273\351\224\201\347\254\224\350\256\260.md" "b/30\345\220\264\350\266\205/\347\254\224\350\256\260/9.22\346\255\273\351\224\201\347\254\224\350\256\260.md" new file mode 100644 index 0000000..1271fd4 --- /dev/null +++ "b/30\345\220\264\350\266\205/\347\254\224\350\256\260/9.22\346\255\273\351\224\201\347\254\224\350\256\260.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/30\345\220\264\350\266\205/\347\254\224\350\256\260/9.26\345\255\230\345\202\250\350\277\207\347\250\213\347\254\224\350\256\260.md" "b/30\345\220\264\350\266\205/\347\254\224\350\256\260/9.26\345\255\230\345\202\250\350\277\207\347\250\213\347\254\224\350\256\260.md" new file mode 100644 index 0000000..76bc943 --- /dev/null +++ "b/30\345\220\264\350\266\205/\347\254\224\350\256\260/9.26\345\255\230\345\202\250\350\277\207\347\250\213\347\254\224\350\256\260.md" @@ -0,0 +1,50 @@ +### 1.存储过程 + +存储过程是一个预编译的SQL语句,优点是允许模块化的设计,就是说只需创建一次,以后在程序中就可以调用多次。如果某次操作需要执行多次SQL,使用存储过程比单纯SQL语句执行要快。可以用一个“execute 存储过程名 参数”命令来调用存储过程。 + +### 2.存储过程的种类 + +##### 系统存储过程 + +以sp_开头,用来进行系统的各项设定.取得信息.相关管理工作。 + +##### 自定义存储过程(本地存储过程) + +以cp_开头,是用户为了完成某一特定功能而创建的存储过程,一般所说的存储过程就是指本地存储过程。 + +##### 临时存储过程 + +分为两种存储过程: + +一是本地临时存储过程,以井字号(#)作为其名称的第一个字符,则该存储过程将成为一个存放在tempdb数据库中的本地临时存储过程,且只有创建它的用户才能执行它; + +二是全局临时存储过程,以两个井字号(##)号开始,则该存储过程将成为一个存储在tempdb数据库中的全局临时存储过程,全局临时存储过程一旦创建,以后连接到服务器的任意用户都可以执行它,而且不需要特定的权限。 + +##### 远程存储过程 + +在SQL Server2005中,远程存储过程(Remote Stored Procedures)是位于远程服务器上的存储过程,通常可以使用分布式查询和EXECUTE命令执行一个远程存储过程。 + +##### 扩展存储过程 + +扩展存储过程(Extended Stored Procedures)是用户可以使用外部程序语言编写的存储过程,而且扩展存储过程的名称通常以xp_开头 + +### 3.如何创建、修改、删除、调用存储过程? + +``` +–创建存储过程 +create proc 存储过程名字 +as +语句 + +–修改存储过程 +alter proc 存储过程名字 +as +语句 + +–卸载存储过程 +drop proc 存储过程名字 + +–调用存储过程 +exec 存储过程名称 +``` + -- Gitee