From a0bc30959e0e7c7f36626c0fc41f44fa78da5aaf Mon Sep 17 00:00:00 2001 From: 13067078163 <921978039@qq.com> Date: Thu, 15 Sep 2022 10:43:05 +0800 Subject: [PATCH 1/3] 0 --- .../9.15 \350\247\206\345\233\276.md" | 76 +++++++++++++++++++ 1 file changed, 76 insertions(+) create mode 100644 "05 \351\273\204\347\202\234\346\235\260/\347\254\224\350\256\260/9.15 \350\247\206\345\233\276.md" diff --git "a/05 \351\273\204\347\202\234\346\235\260/\347\254\224\350\256\260/9.15 \350\247\206\345\233\276.md" "b/05 \351\273\204\347\202\234\346\235\260/\347\254\224\350\256\260/9.15 \350\247\206\345\233\276.md" new file mode 100644 index 0000000..d664e98 --- /dev/null +++ "b/05 \351\273\204\347\202\234\346\235\260/\347\254\224\350\256\260/9.15 \350\247\206\345\233\276.md" @@ -0,0 +1,76 @@ +### 什么是视图? + +在 SQL 中,视图是基于 SQL 语句的结果集的可视化的表。 + +视图包含行和列,就像一个真实的表。视图中的字段就是来自一个或多个数据库中的真实的表中的字段。我们可以向视图添加 SQL 函数、WHERE 以及 JOIN 语句,我们也可以提交数据,就像这些来自于某个单一的表。 + +**注释:**数据库的设计和结构不会受到视图中的函数、where 或 join 语句的影响。 + +### SQL CREATE VIEW 语法 + +```sql +CREATE VIEW view_name AS +SELECT column_name(s) +FROM table_name +WHERE condition +``` + +**注释:**视图总是显示最近的数据。每当用户查询视图时,数据库引擎通过使用 SQL 语句来重建数据。 + +## SQL CREATE VIEW 实例 + +可以从某个查询内部、某个存储过程内部,或者从另一个视图内部来使用视图。通过向视图添加函数、join 等等,我们可以向用户精确地提交我们希望提交的数据。 + +样本数据库 Northwind 拥有一些被默认安装的视图。视图 "Current Product List" 会从 Products 表列出所有正在使用的产品。这个视图使用下列 SQL 创建: + +```sql +CREATE VIEW [Current Product List] AS +SELECT ProductID,ProductName +FROM Products +WHERE Discontinued=No +``` + +我们可以查询上面这个视图: + + + +```sql +SELECT * FROM [Current Product List] +``` + +Northwind 样本数据库的另一个视图会选取 Products 表中所有单位价格高于平均单位价格的产品: + +```sql +CREATE VIEW [Products Above Average Price] AS +SELECT ProductName,UnitPrice +FROM Products +WHERE UnitPrice>(SELECT AVG(UnitPrice) FROM Products) +``` + +我们可以像这样查询上面这个视图: + +```sql +SELECT * FROM [Products Above Average Price] +``` + +另一个来自 Northwind 数据库的视图实例会计算在 1997 年每个种类的销售总数。请注意,这个视图会从另一个名为 "Product Sales for 1997" 的视图那里选取数据: + +```sql +CREATE VIEW [Category Sales For 1997] AS +SELECT DISTINCT CategoryName,Sum(ProductSales) AS CategorySales +FROM [Product Sales for 1997] +GROUP BY CategoryName +``` + +我们可以像这样查询上面这个视图: + +```sql +SELECT * FROM [Category Sales For 1997] +``` + +我们也可以向查询添加条件。现在,我们仅仅需要查看 "Beverages" 类的全部销量: + +```sql +SELECT * FROM [Category Sales For 1997] +WHERE CategoryName='Beverages' +``` \ No newline at end of file -- Gitee From 14233c81efb1898f06f944959d400f46966f7657 Mon Sep 17 00:00:00 2001 From: 13067078163 <921978039@qq.com> Date: Wed, 21 Sep 2022 17:11:47 +0800 Subject: [PATCH 2/3] 0 --- .../9.20 \346\270\270\346\240\207.txt" | 78 +++++++++++ .../9.7\344\275\234\344\270\232.txt" | 0 .../9.19 \344\272\213\345\212\241.md" | 45 +++++++ .../9.20 \346\270\270\346\240\207.md" | 124 ++++++++++++++++++ .../9.21 \345\207\275\346\225\260.md" | 114 ++++++++++++++++ 5 files changed, 361 insertions(+) create mode 100644 "05 \351\273\204\347\202\234\346\235\260/\344\275\234\344\270\232/9.20 \346\270\270\346\240\207.txt" rename "05 \351\273\204\347\202\234\346\235\260/\344\275\234\344\270\232/9.7\344\275\234\344\270\232.md" => "05 \351\273\204\347\202\234\346\235\260/\344\275\234\344\270\232/9.7\344\275\234\344\270\232.txt" (100%) create mode 100644 "05 \351\273\204\347\202\234\346\235\260/\347\254\224\350\256\260/9.19 \344\272\213\345\212\241.md" create mode 100644 "05 \351\273\204\347\202\234\346\235\260/\347\254\224\350\256\260/9.20 \346\270\270\346\240\207.md" create mode 100644 "05 \351\273\204\347\202\234\346\235\260/\347\254\224\350\256\260/9.21 \345\207\275\346\225\260.md" diff --git "a/05 \351\273\204\347\202\234\346\235\260/\344\275\234\344\270\232/9.20 \346\270\270\346\240\207.txt" "b/05 \351\273\204\347\202\234\346\235\260/\344\275\234\344\270\232/9.20 \346\270\270\346\240\207.txt" new file mode 100644 index 0000000..65706f8 --- /dev/null +++ "b/05 \351\273\204\347\202\234\346\235\260/\344\275\234\344\270\232/9.20 \346\270\270\346\240\207.txt" @@ -0,0 +1,78 @@ +use STUDENTS +go + +--αװ + +declare mycur cursor scroll for (select * from StuInfo) + +open mycur + +fetch first from mycur +--ѭ ѧϢ + +select * from tb_student +select * from tb_inf_student +select * from tb_bibliography +select * from tb_book +select * from tb_record + + +--- ѧα꣬α(ѧ,Ȥ,Դأ) +declare student cursor scroll for select name,hobby,ori_loca,prize from tb_student,tb_inf_student +open student +fetch first from student +close student +--- ѭ161ͷѧϢ +declare qwe cursor scroll for (select * from tb_student where stu_num like '161%') +declare @number nvarchar(20),@name varchar(20),@gender varchar(20),@birth varchar(20),@school varchar(20),@major varchar(20) +open qwe +fetch first from qwe + +while(@@FETCH_STATUS=0) +begin +print 'ѧ:'+@number+' :'+@name+' gender:'+@gender+' :'+@birth+' ѧԺ:'+@school+' רҵ:'+@major +fetch next from qwe into @number,@name,@gender,@birth,@school,@major +end +close qwe + + +--- ʹαͳԴΪ +declare qqq cursor scroll for (select prize from tb_inf_student where ori_loca like '') +declare @ji int = 0 +declare @sum int =0 +open qqq +fetch first from qqq into @ji +while(@@FETCH_STATUS=0) +begin +set @sum += @ji; +fetch next from qqq into @ji +end +close qqq +print' :'+cast(@sum as varchar(10)) +deallocate qqq + +--- ʹα5-1ǰѧͼ黹 + +declare books cursor scroll for(select * from tb_record where borrow_time<'2019-05-01' and return_time is null) +open books +begin transaction + + declare @nums int=0 + update tb_record set return_time=GETDATE() where borrow_time<'2019-05-01'and return_time is null + set @nums += @@ERROR + +print @nums +if @nums>0 + begin + print 'δ黹' + rollback transaction + end +else + begin + print 'ѹ黹' + commit transaction + end + + +close books +select * from tb_record \ No newline at end of file diff --git "a/05 \351\273\204\347\202\234\346\235\260/\344\275\234\344\270\232/9.7\344\275\234\344\270\232.md" "b/05 \351\273\204\347\202\234\346\235\260/\344\275\234\344\270\232/9.7\344\275\234\344\270\232.txt" similarity index 100% rename from "05 \351\273\204\347\202\234\346\235\260/\344\275\234\344\270\232/9.7\344\275\234\344\270\232.md" rename to "05 \351\273\204\347\202\234\346\235\260/\344\275\234\344\270\232/9.7\344\275\234\344\270\232.txt" diff --git "a/05 \351\273\204\347\202\234\346\235\260/\347\254\224\350\256\260/9.19 \344\272\213\345\212\241.md" "b/05 \351\273\204\347\202\234\346\235\260/\347\254\224\350\256\260/9.19 \344\272\213\345\212\241.md" new file mode 100644 index 0000000..d86f85c --- /dev/null +++ "b/05 \351\273\204\347\202\234\346\235\260/\347\254\224\350\256\260/9.19 \344\272\213\345\212\241.md" @@ -0,0 +1,45 @@ +## 事务 + +#### 什么是事务 + +**事务( 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/05 \351\273\204\347\202\234\346\235\260/\347\254\224\350\256\260/9.20 \346\270\270\346\240\207.md" "b/05 \351\273\204\347\202\234\346\235\260/\347\254\224\350\256\260/9.20 \346\270\270\346\240\207.md" new file mode 100644 index 0000000..f628259 --- /dev/null +++ "b/05 \351\273\204\347\202\234\346\235\260/\347\254\224\350\256\260/9.20 \346\270\270\346\240\207.md" @@ -0,0 +1,124 @@ +**1.1游标的概念** + +  游标(Cursor)它使用户可逐行访问由SQL Server返回的结果集。使用游标(cursor)的一个主要的原因就是把集合操作转换成单个记录处理方式。用SQL语言从数据库中检索数据后,结果放在内存的一块区域中,且结果往往是一个含有多个记录的集合。游标机制允许用户在SQL server内逐行地访问这些记录,按照用户自己的意愿来显示和处理这些记录。 + +  **1.2 游标的优点** + +  从游标定义可以得到游标的如下优点,这些优点使游标在实际应用中发挥了重要作用: + +  1)允许程序对由查询语句select返回的行集合中的每一行执行相同或不同的操作,而不是对整个行集合执行同一个操作。 + +  2)提供对基于游标位置的表中的行进行删除和更新的能力。 + +  3)游标实际上作为面向集合的数据库管理系统(RDBMS)和面向行的程序设计之间的桥梁,使这两种处理方式通过游标沟通起来。 + +  **1.3 游标的使用** + +  讲了这个多游标的优点,现在我们就亲自来揭开游标的神秘的面纱。 + +  使用游标的顺序: 声名游标、打开游标、读取数据、关闭游标、删除游标。 + +  **1.3.1声明游标** + +  最简单游标声明:DECLARE <游标名>CURSOR FOR; + +  其中select语句可以是简单查询,也可以是复杂的接连查询和嵌套查询 + +  例子:[已表2 AddSalary为例子] + +  Declare mycursor cursor for select * from AddSalary 这样我就对表AddSalary申明了一个游标mycursor + +  【高级备注】 + +  DECLARE <游标名> [INSENSITIVE] [SCROLL] CURSORFOR 这里我说一下游标中级应用中的[INSENSITIVE]和[SCROLL] + +  INSENSITIVE + +  表明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 极大地增加了提取数据的灵活性,可以随意读取结果集中的任一行数据记录,而不必关闭再重开游标。 + +  **1.3.2 打开游标** + +  非常简单,我们就打开刚才我们声明的游标mycursor + +  OPEN mycursor + +  **1.3.3读取数据** + +FETCH [ NEXT | PRIOR | FIRST | LAST] FROM { 游标名 | @游标变量名 } [ INTO @变量名 [,…] ] + +  参数说明: + +  NEXT 取下一行的数据,并把下一行作为当前行(递增)。由于打开游标后,行指针是指向该游标第1行之前,所以第一次执行FETCH NEXT操作将取得游标集中的第1行数据。NEXT为默认的游标提取选项。 + +  INTO @变量名[,…] 把提取操作的列数据放到局部变量中。列表中的各个变量从左到右与游标结果集中的相应列相关联。各变量的数据类型必须与相应的结果列的数据类型匹配或是结果列数据类型所支持的隐性转换。变量的数目必须与游标选择列表中的列的数目一致。 + +  **1.3.5删除游标** + +  DEALLOCATE mycursor + +  **1.3.6 实例训练** + +  如上我介绍完了游标使用的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/05 \351\273\204\347\202\234\346\235\260/\347\254\224\350\256\260/9.21 \345\207\275\346\225\260.md" "b/05 \351\273\204\347\202\234\346\235\260/\347\254\224\350\256\260/9.21 \345\207\275\346\225\260.md" new file mode 100644 index 0000000..da1d900 --- /dev/null +++ "b/05 \351\273\204\347\202\234\346\235\260/\347\254\224\350\256\260/9.21 \345\207\275\346\225\260.md" @@ -0,0 +1,114 @@ +# 函数 + +函数分为 + +- (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 +``` + -- Gitee From 2df59e4c39c2bd1c78575c0937633705476b6bb9 Mon Sep 17 00:00:00 2001 From: unknown <“921978039@qq.com”> Date: Wed, 21 Sep 2022 22:41:29 +0800 Subject: [PATCH 3/3] 0 --- .../9.21 \345\207\275\346\225\260.txt" | 60 +++++++++++++++++++ 1 file changed, 60 insertions(+) create mode 100644 "05 \351\273\204\347\202\234\346\235\260/\344\275\234\344\270\232/9.21 \345\207\275\346\225\260.txt" diff --git "a/05 \351\273\204\347\202\234\346\235\260/\344\275\234\344\270\232/9.21 \345\207\275\346\225\260.txt" "b/05 \351\273\204\347\202\234\346\235\260/\344\275\234\344\270\232/9.21 \345\207\275\346\225\260.txt" new file mode 100644 index 0000000..c95492a --- /dev/null +++ "b/05 \351\273\204\347\202\234\346\235\260/\344\275\234\344\270\232/9.21 \345\207\275\346\225\260.txt" @@ -0,0 +1,60 @@ +--(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') + + +--方案一(逻辑复杂,函数内容除了返回结果的sql语句还有其他内容,例如定义变量等): + +--(4)查询银行卡信息,将银行卡状态1,2,3,4分别转换为汉字“正常,挂失,冻结,注销”,根据银行卡余额显示银行卡等级 30万以下为“普通用户”,30万及以上为"VIP用户",分别显示卡号,身份证,姓名,余额,用户等级,银行卡状态。 + + + + +--方案一:直接在sql语句中使用case when + +--方案二:将等级和状态用函数实现 + +--(5)编写函数,根据出生日期求年龄,年龄求实岁,例如: + + + +--​ 生日为2000-5-5,当前为2018-5-4,年龄为17岁 +--​ 生日为2000-5-5,当前为2018-5-6,年龄为18岁 \ No newline at end of file -- Gitee