From 4e77ec38b8ca18f831a4729521657e4f615a7d02 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=A9=B9=E6=BA=90=E9=93=A0?= <1905540517@qq.com> Date: Wed, 21 Sep 2022 23:42:17 +0800 Subject: [PATCH 1/4] =?UTF-8?q?=E7=AC=94=E8=AE=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../9.19\344\272\213\345\212\241.md" | 108 ++++++++++++++++++ 1 file changed, 108 insertions(+) create mode 100644 "23\350\251\271\346\272\220\351\223\240/\347\254\224\350\256\260/9.19\344\272\213\345\212\241.md" diff --git "a/23\350\251\271\346\272\220\351\223\240/\347\254\224\350\256\260/9.19\344\272\213\345\212\241.md" "b/23\350\251\271\346\272\220\351\223\240/\347\254\224\350\256\260/9.19\344\272\213\345\212\241.md" new file mode 100644 index 0000000..a1b73d5 --- /dev/null +++ "b/23\350\251\271\346\272\220\351\223\240/\347\254\224\350\256\260/9.19\344\272\213\345\212\241.md" @@ -0,0 +1,108 @@ +```` +# 七、事务 + +- **事务是作为单个逻辑的工作单元执行的一系列操作** +- **多个操作作为一个整体向系统提交,要么都执行,要么都不执行** +- **事务是一个不可分割的逻辑单元** + +## (一)事务的特点 + +**原子性**:事务是一个完整的操作,事务的各步操作是不可分的(原子的)事务内的所有工作**要么全部完成,要么全部没有完成** +**一致性**:事务内的任何操作都不能违反数据库的任何约束或规则 +**隔离性**:并发事务之间彼此隔离、独立,它不应该以任何方式依赖于或影响其他事务 +**持久性**:事务完成后,他对数据库的影响是持久的 + +#### 事务执行流程 + +![](https://gitee.com/wumingjie0606/tuchuang/raw/master/img/2022-9-1919:57:20-1663588630151.png) + +****** + +## (二)事务处理 + +开始事务:标记一个本地事务的开始 + +```sql +begin transaction +``` + +提交事务:全部执行完,用于提交事务 + +```sql +commit transaction +``` + +回滚(撤销)事务:用于事务回滚,有一条语句出错就回滚 + +```sql +rollback transaction +``` + +#### 1.注意事项 + +- **一旦事务提交或回滚,则事务结束** +- **事务可以嵌套** +- ==**使用@@error全局变量记录执行过程中的错误**== + +****** + +#### 2.判断某条语句执行是否出错 + +- 使用全局变量@@error +- @@error只判断当前一条T-SQL语句执行是否有错 +- 为了判断事务中所有SQL语句是否有错,==可以对错误进行累计== + +例: + +```sql +set @errorSum=@errorSum+@@error +``` + +****** + +#### 3.完整代码示例 + +假设所有事务处理转账 + +```sql +begin transaction--开始事务 + declare @errorsum int --声明计数器 + set @errorsum=0 --初始化 + update bank set currentmoney-500 where name='张三'--转账操作 + set @errorsum=@errorSum+@@error --错误语句计数 + update bank set currentmoney+500 where name='李四' + set @errorsum=@errorSum+@@error +if(@errorsum>0)--如果错误数大于0 + begin + print'转账失败' + rollback transaction--回滚事务 + end +else + begin + print'转账失败' + commit transaction--提交事务 + end +go +``` + +****** + +## (三)事务分类 + +### 1.显式事务 + +- 用BEGIN TRANSACTION明确指定事务的开始 +- **最常用的事务类型** + +### 2.隐性事务(不常用) + +- 通过设置SET IMPLICIT_TRANSACTIONS ON 语句,将隐性事务模式设置为打开 +- 其后的T-SQL语句自动启动一个新事务 +- 提交或回滚一个事务后,下一个T-SQL语句又将启动一个新事务 +- select,update,insert,delect本身就是一个隐性事务? + +### 3.自动提交 + +- 事务SQL Server 的默认模式 +- 每条单独的T-SQL语句视为一个事务 +```` \ No newline at end of file -- Gitee From 6b7ff436138c9a60661a9680d0ad5ebea26d25e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=A9=B9=E6=BA=90=E9=93=A0?= <1905540517@qq.com> Date: Wed, 21 Sep 2022 23:44:13 +0800 Subject: [PATCH 2/4] biji --- .../9.20\346\270\270\346\240\207.md" | 277 ++++++++++++++++++ 1 file changed, 277 insertions(+) create mode 100644 "23\350\251\271\346\272\220\351\223\240/\347\254\224\350\256\260/9.20\346\270\270\346\240\207.md" diff --git "a/23\350\251\271\346\272\220\351\223\240/\347\254\224\350\256\260/9.20\346\270\270\346\240\207.md" "b/23\350\251\271\346\272\220\351\223\240/\347\254\224\350\256\260/9.20\346\270\270\346\240\207.md" new file mode 100644 index 0000000..d483b86 --- /dev/null +++ "b/23\350\251\271\346\272\220\351\223\240/\347\254\224\350\256\260/9.20\346\270\270\346\240\207.md" @@ -0,0 +1,277 @@ +```` +# 八、游标 + + +可以将游标看作一种特殊的指针,SQL的游标是一种临时的数据库对象,既可以存放储存在数据库表中数据行的副本,也指向数据行的指针。 + +使用游标,可以实现以下目标 +● 允许定位到结果集中的特定行 +● 从结果集的当前位置检索一行或多行数据 +● 支持对结果集中当前位置的行进行修改 + +## (一)T-SQL游标的分类 + +- **静态游标(Static)** : 在操作游标的时候,数据发生变化,游标中数据不变 +- **动态游标(Dynamic)**: 在操作游标的时候,数据发生变化,游标中数据改变,默认值。 +- **只进游标**:只进游标不支持滚动,只支持从头到尾顺序提取数据,数据库执行增删改,在提取时是可见的,但由于该游标只能进不能向后滚动,所以在行提取后对行做增删改是不可见的。 +- **键集驱动游标(KeySet)**:在操作游标的时候,被标识的列发生改变,游标中数据改变,其他列改变,游标中数据不变。 + +********* + +### 1.游标的生命周期与使用步骤 + +使用游标前4个步骤是必须的 + +- **声明游标** declare:将游标与 T-SQL 语句的结果集相关联,并定义游标的名称、类型和属性,如游标中的记录是否可以更新、删除 + +- ```sql + --1.创建游标(Scroll代表滚动游标,不加Scroll则是只进的,只能支持fetch next) + declare <游标名> cursor scroll for select stuname from stuinfo + ``` + +- **打开游标** open:执行 T-SQL 语句以填充数据。 + +- ```sql + open <游标名> + ``` + + + +- **读取游标** fetch:从游标的结果集中检索想要查看的行,进行逐步操作。 + +- ```sql + fetch first from <游标名> --结果集的第一行 + fetch last from <游标名> --最后一行 + fetch absolute 1 from <游标名> --从游标的第一行开始数,第n行。 + fetch relative 3 from <游标名> --从当前位置数,第n行。 + fetch next from <游标名> --当前位置的下一行 + fetch prior from <游标名> --当前位置的上一行 + ``` + + + +- **关闭游标** close:停止游标使用的查询,但并不删除游标的定义,可以使用 OPEN 再次打开。 + +- ```sql + close <游标名> + ``` + + + +- **释放游标** DEALLOCATE:删除资源并释放其占用的所有资源。 + +**游标的生命周期就包含上面五个阶段** + +************* + +## (二)声明游标cursor + +声明游标是指用 DECLARE 语句创建一个游标。声明游标主要包括以下内容:游标名称、数据来源、选取条件和属性。 + +```sql +declare 游标名称 cursor[local|global]--游标的作用域 +[forward_only|scroll] --游标的移动方向 +[STATIC|KEYSET|DYNAMIC|FAST_FORWARD]--游标的类型 +[READ_ONLY|SCROLL_LOCKS|OPTIMISTIC]--游标的访问类型 +[TYPE_WARNING] --类型转换警告语句 +for select 语句 --select查询语句 +[for{read only|update[of 列名称]}][,...n]--可修改的列 +``` + +参数说明: + +- [Local | Global] :默认为local +- Local:作用域为局部,只在定义它的批处理,存储过程或触发器中有效。 +- Global:作用域为全局,由连接执行的任何存储过程或批处理中,都可以引用该游标。 + +- Scroll:代表滚动游标,不加Scroll则是只进的,只能支持fetch next +- forward_only:指定游标智能从第一行滚到最后一行。Fetch Next是唯一支持的提取选项。如果在指定Forward_Only是不指定Static、KeySet、Dynamic关键字,默认为Dynamic游标。如果Forward_Only和Scroll没有指定,Static、KeySet、Dynamic游标默认为Scroll,Fast_Forward默认为Forward_Only + +- Static:静态游标 +- KeySet:键集游标 +- Dynamic:动态游标,不支持Absolute提取选项 +- Fast_Forward:指定启用了性能优化的Forward_Only、Read_Only游标。如果指定啦Scroll或For_Update,就不能指定他啦。 + + +- Read_Only:不能通过游标对数据进行删改。 +- Scroll_Locks:将行读入游标是,锁定这些行,确保删除或更新一定会成功。如果指定啦Fast_Forward或Static,就不能指定他啦。 +- Optimistic:指定如果行自读入游标以来已得到更新,则通过游标进行的定位更新或定位删除不成功。当将行读入游标时,sqlserver不锁定行,它改用timestamp列值的比较结果来确定行读入游标后是否发生了修改,如果表不行timestamp列,它改用校验和值进行确定。如果已修改改行,则尝试进行的定位更新或删除将失败。如果指定啦Fast_Forward,则不能指定他。 + +- Type_Warning:指定将游标从所请求的类型隐式转换为另一种类型时向客户端发送警告信息。 +- For Update[of column_name ,....] :定义游标中可==更新==的列。 + +********** + +**示例:** + +```sql +declare student cursor for select * from btb_student +``` + +********* + +## (三)打开游标 + +语法: + +```sql +open 游标名称 |游标变量名称--表示该变量引用了一个游标 +``` + +**在游标被成功打开后,全局 变量 ==@@CORSOR_ROWS== 用来记录游标内的数据行数。返回值有四种:** + +| 返回值 | 描述 | +| ------ | ----------------------------------------------------------- | +| -m | 表示仍在从基础表向游标读入数据,m表示当前在游标中的数据行数 | +| -1 | 该游标是一个动态游标,其返回值无法确定 | +| 0 | 无符合调剂的记录或游标已经关闭 | +| n | 从基础表向游标读入数据已结束,n 为游标中已有的数据记录行数 | + +**示例:打开游标,输出游标中的行数** + +```sql +open curl +select '游标curl数据行数'=@@cursor_rows +``` + +*************** + +## (四)读取游标 + +**当游标打开后就可以使用 FETCH 命令从游标中逐行地读取数据,以进行相关处理。** + +语法:fetch[取来] + +```sql +fetch +[[next|prior|first|last|absoute n|relative n]from]--读取数据位置 +[global]游标名称--或者@游标变量名称 [into @游标变量名称][,...n] +``` + +**参数说明:** + +- First:结果集的第一行 +- Prior:当前位置的上一行 +- Next:当前位置的下一行 +- Last:最后一行 +- Absoute n:从游标的第一行开始数,第n行。 +- Relative n:从当前位置数,第n行。 +- Into @variable_name[,...] : 将提取到的数据存放到变量variable_name中。 + +**示例:** + +**提取数据给变量以供它用(取出第3行学生姓名,查询该学生详细信息):** + +```sql +declare @vari varchar(20) +fetch absolute 3 from <游标名> into @vari +select * from StuInfo where stuName = @vari +``` + +**利用游标更新数据**: + +```sql +--更新语法: +-- fetch absolute 3 from <游标名> +-- update 语句 where Current of <游标名> +``` + +********* + +*********** + +fetch语句执行时,**==可以使用 全局变量 @@FETCH_STATUS 返回上次执行 fetch 命令的状态。==**在每次用 fetch 从游标中读取数据时,都应检查该变量,以确定上次fetch操作是否成功,来决定如何进行下一步处理。**返回值有三种:** + +| 返回值 | 描述 | +| ------ | ----------------------------------------------- | +| 0 | FETCH命令被成功执行 | +| 1 | FETCH命令失败或者行数据超过游标数据结果集的范围 | +| 2 | 所读取的数据已经不存在 | + +*********** + +**示例:创建游标 curl,从游标中提取数据,并查看 FETCH 命令的执行状态。** + +```sql +fetch next from curl +select 'next_fetch执行情况'=@@FETCH_STATUS +``` + +*************** + +## (五)关闭游标 + +**游标使用完以后要及时关闭。关闭游标使用 CLOSE ,但不释放游标占用的资源。** + +语法: + +```sql +close [global] 游标名称|游标变量名称 +``` + +************ + +## (六)删除游标 + +**游标关闭后定义还在,需要时可以再使用 OPEN 打开游标继续使用。若确定不再使用则使用 CLOSE 删除游标,释放占用系统中的资源。** + +语法: + +```sql +deallocate [Global] 游标名称|游标变量名称 +``` + +******** + +## (七)完整的步骤演示 + +```sql +--定义一个游标 +declare游标名 cursor scroll for select字段列表 from 表名 +--打开游标 +open 游标名 +--定义变量,用于存放游标读取出来的值 +declare @xxx 数据类型 +--读取游标的第一条数据,并存放在变量中 +fetch first from 游标名 into @xxx +--循环记录游标读取的数据 +print '读取的数据如下:' +while(@@FETCH_STATUS =0) + begin + --使用print输出读取的数据 + print'文字说明:'+xxx + --读取下一条记录 + fetch next from 游标名 into @xxx + end +--读取完成后关闭游标 +close 游标名 +go +--删除游标 +deallocate 游标名 +go +``` + +例题:**创建游标指向某行多列数据,并循环显示数据:** + +```sql +--此处如果指向所有数据,可以将for后面的语句修改成select * from stuinfo +declare <游标名> cursor scroll +declare mycursor cursor scroll for select stuname,StuSex,ClassID from stuinfo + +open <游标名> + +declare @name varchar(20) +declare @sex varchar(2) +declare @cid int +fetch first from mycursor into @name,@sex,@cid +while @@FETCH_STATUS=0 +fetch next from <游标名> into into @name,@sex,@cid + +while @@FETCH_STATUS = 0 --@@FETCH_STATUS=0,提取成功,-1提取失败,-2行不存在 + begin + print '提取成功' + fetch next from CURSORMember into@into @name,@sex,@cid + end +close <游标名> +``` +```` \ No newline at end of file -- Gitee From 8a085d38f74544d911a1970d8c53e54946d438a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=A9=B9=E6=BA=90=E9=93=A0?= <1905540517@qq.com> Date: Wed, 21 Sep 2022 23:46:36 +0800 Subject: [PATCH 3/4] biji --- .../9.21\345\207\275\346\225\260.md" | 69 +++++++++++++++++++ 1 file changed, 69 insertions(+) create mode 100644 "23\350\251\271\346\272\220\351\223\240/\347\254\224\350\256\260/9.21\345\207\275\346\225\260.md" diff --git "a/23\350\251\271\346\272\220\351\223\240/\347\254\224\350\256\260/9.21\345\207\275\346\225\260.md" "b/23\350\251\271\346\272\220\351\223\240/\347\254\224\350\256\260/9.21\345\207\275\346\225\260.md" new file mode 100644 index 0000000..90cb842 --- /dev/null +++ "b/23\350\251\271\346\272\220\351\223\240/\347\254\224\350\256\260/9.21\345\207\275\346\225\260.md" @@ -0,0 +1,69 @@ +```` +# 函数 + +自定义函数/方法: + + 封装代码,重复使用,减少代码重复性 + + + +### 语句 + +##### 标量值函数 + + 只返回一个值 + +创建函数 + +```sql +create function 函数名(参数名 参数类型) +returns 返回值类型 +begin +--写结构体的地方 + …… + + return 返回值 +end +``` + +调用函数 + +```sql +select function dbo.函数名 +``` + + + +##### 表值函数 + + 返回一个表的数据 + +创建函数 + +```sql +create function 函数名(参数名 参数类型) +returns 新创建的表名 table (字段名 数据类型,字段名 数据类型,……) +begin +--如果要插入数据 + insert into 新建的表名 +--接上查询语句 + select…… + + retutn +end +``` + +调用函数 + +```sql +select * from dbo.函数名(参数值) +``` + + + +##### 删除函数 + +```sql +drop function 函数名 +``` +```` \ No newline at end of file -- Gitee From c57f8db184f392cf6ee54523873b9c21f1ad2fee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=A9=B9=E6=BA=90=E9=93=A0?= <1905540517@qq.com> Date: Wed, 21 Sep 2022 23:55:36 +0800 Subject: [PATCH 4/4] bij --- .../9.21\345\207\275\346\225\260\343\200\202.md" | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename "23\350\251\271\346\272\220\351\223\240/\347\254\224\350\256\260/9.21\345\207\275\346\225\260.md" => "23\350\251\271\346\272\220\351\223\240/\347\254\224\350\256\260/9.21\345\207\275\346\225\260\343\200\202.md" (100%) diff --git "a/23\350\251\271\346\272\220\351\223\240/\347\254\224\350\256\260/9.21\345\207\275\346\225\260.md" "b/23\350\251\271\346\272\220\351\223\240/\347\254\224\350\256\260/9.21\345\207\275\346\225\260\343\200\202.md" similarity index 100% rename from "23\350\251\271\346\272\220\351\223\240/\347\254\224\350\256\260/9.21\345\207\275\346\225\260.md" rename to "23\350\251\271\346\272\220\351\223\240/\347\254\224\350\256\260/9.21\345\207\275\346\225\260\343\200\202.md" -- Gitee