目录
事务
一、事务概念
转账问题 :假定张三给李四转钱,至少需要两步: 张三的钱减少 、李四的钱增加
事务是一种机制、是一种操作序列,它包含了一组数据库操作命令,这组命令要么全部执行,要么全部不执行。因此事务是一个不可分割的工作逻辑单元。在数据库系统上执行并发操作时事务是作为最小的控制单元来使用的。这特别适用于多用户同时操作的数据通信系统。例如:订票、银行、保险公司以及证券交易系统等。
v语法步骤:
- ü开始事务:BEGIN TRANSACTION
- ü提交事务:COMMIT TRANSACTION
- ü回滚事务:ROLLBACK TRANSACTION
v判断某条语句是否出错
全局变量:@@ERROR;无错返回0,否则:<>0
它只能判断当前语句是否出错,为了判断事务中是否所有SQL语句有错,需要对错误进行累计:
例:set @ErrorSum= @ErrorSum+@@ERROR
v隐式事务:每次执行一条SQL语句的时候,系统自动帮我们打开一个事务,但是需要手动提交或回滚。
SET IMPLICIT_TRANSACTIONS ON;
二、事务属性
原子性(Atomicity):事务是一个完整的操作。 事务必须是原子工作单元
v一致性(Consistency):事务在完成时,必须使所有的数据都保持一致状态。
v隔离性(Isolation):对数据进行修改的所有并发事务是彼此隔离的。
v持久性(Durability):事务完成之后,它对于系统的影响是永久性的。该修改即使出现致命的系统故障也将一直保持。
三、创建事务
v开始事务: begin transaction
v提交事务:commit transaction
v回滚事务: rollback transaction
Ado中使用事务------SqlTransaction:类
注意:
1、操作事务的时候,必须添加try-catch
2、事务开始之前就要必须把连接打开
v关键代码:
/// <summary>
/// 2给1转账100
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void button1_Click(object sender, EventArgs e)
{
//创建Connection对象
using (SqlConnection con=new SqlConnection(strCon))
{
//打开数据库连接
con.Open();
//创建一个事务对象,开始事务
SqlTransaction sqlTrans = con.BeginTransaction();
try
{
//创建COmmand对象
SqlCommand cmd = new SqlCommand();
cmd.Connection = con; //关联Connection
cmd.Transaction = sqlTrans; //关联事务队形
string sql1 = string.Format("update bank set balance=balance-{0} where cId='0002';", textBox1.Text.Trim());
string sql2 = string.Format("update bank set balance=balance+{0} where cId='0001';", textBox1.Text.Trim());
cmd.CommandText = sql1 + sql2; //将sql语句赋值给Command
int n=cmd.ExecuteNonQuery();
if (n > 0)
{
label2.Text = "转账成功!";
}
else
{
label2.Text = "转账失败!";
}
//提交事务
sqlTrans.Commit();
}
catch (Exception ex)
{
//回滚事务
sqlTrans.Rollback();
con.Close();
}
}
}
注意事项:
如下的SQL语句不允许出现在事务中:
ALTER DATABASE | 修改数据库 |
BACKUP LOG | 备份日志 |
CREATE DATABASE | 创建数据库 |
DISK INIT | 创建数据库或事务日志设备 |
DROP DATABASE | 删除数据库 |
DUMP TRANSACTION | 转储事务日志 |
LOAD DATABASE | 装载数据库备份复本 |
LOAD TRANSACTION | 装载事务日志备份复本 |
RECONFIGURE | 更新使用 sp_configure 系统存储过程更改的配置选项的当前配置(sp_configure 结果集中的 config_value 列)值。 |
RESTORE DATABASE | 还原使用BACKUP命令所作的数据库备份 |
RESTORE LOG | 还原使用BACKUP命令所作的日志备份 |
UPDATE STATISTICS | 在指定的表或索引视图中,对一个或多个统计组(集合)有关键值分发的信息进行更新 |
游标
一、游标概念
v游标是SQL Server的一种数据访问机制,它允许用户访问单独的数据行。用户可以对每一行进行单独的处理,从而降低系统开销和潜在的阻隔情况,用户也可以使用这些数据生成的SQL代码并立即执行或输出。
v游标主要用于存储过程,触发器和 T_SQL脚本中,它们使结果集的内容可用于其它T_SQL语句在查看或处理结果集中向前或向后浏览数据的功能。类似与C语言中的指针,它可以指向结果集中的任意位置,当要对结果集进行逐条单独处理时,必须声明一个指向该结果集中的游标变量。
优点:
游标能从包括多条记录的结果集中每次提取一条记录,由结果集和指向特定记录的游标位置组成。
游标具有以下优点:
- v允许程序对由SELECT查询语句返回的行集中的每一次执行相同或不同的操作,而不是对整个集合执行同一个操作
- v提供对基于游标位置中的行进行删除和更新的能力。
- v游标作为数据库管理系统和应用程序设计之间的桥梁,将两种处理方式连接起来。
分类:
- vTransact_SQL游标:服务器上实现,由SQL语句管理
- v应用程序编程接口(API)服务器游标:服务器上实现,客户端调用API游标函数,由接口或驱动程序传给服务器
- v客户端游标:在客户端缓存所有结果集中的行,由API函数通过接口或驱动程序调用缓存结果集中的行
- Ø只进游标:不支持滚动,支持从头到尾顺序读取
- Ø静态游标:始终只读,打开游标时结果集建立在tempdb中,按照打开时的原样显示结果集。 静态游标不会显示打开游标以后在数据库中新插入的行。
- Ø由键驱动的游标: 各行的成员身份和顺序固定。由键集驱动的游标由一组唯一标识符(键)控制,这组键成为键集。
- Ø动态游标:当滚动游标时,动态游标反映结果集中所做的所有更改。
二、游标的操作
1.声明
游标构成:游标结果集+游标位置
- 游标结果集:游标的SELECT语句返回的行集合
- 游标位置:指向这个结果集中某一行的指针。
创建游标简单应用
declare test_cur cursor for --创建游标
select employeeName,employeeDept from tb_employee;
open test_cur --打开游标
fetch next from test_cur --从游标变量中读取值
while @@FETCH_STATUS=0 --判断fetch语句是否执行成功(0:成功 -1:fetch语句失败或此行不在结果集中 -2:被提取的行不在)
begin
fetch next from test_cur --读取游标变量中的数据
end
close test_cur --关闭游标
deallocate test_cur --释放游标
2.Fetch语法格式
vFETCH [ [ NEXT | PRIOR | FIRST | LAST | ABSOLUTE { n | @nvar } | RELATIVE { n | @nvar } ] FROM
vABSOLUTE:如果n或@nvar为正,则返回从游标头开始向后n行的第n行,并将返回行变成新的当前行。如果n或@nvar为负,则返回从游标末尾开始向前的n行的第n行,并将返回行变成新的当前行。如果n或@nvar为0,则不返回行。n必须是整数常量,并且@nvar的数据类型必须为int、tinyint或smallint.
vRELATIVE:如果n或@nvar为正,则返回从当前行开始向后的第n行。如果n或@nvar为负,则返回从当前行开始向前的第n行。如果n或@nvar为0,则返回当前行,对游标第一次提取时,如果在将n或@nvar设置为负数或0的情况下指定FETCH RELATIVE,则不返回行,n必须是整数常量,@nvar的数据类型必须是int、tinyint或smallint.
eg:v创建游标cursor_variable,将fruits表中的记录f_name,f_price值赋给变量@fruitName和@fruitPrice,并打印输出。
eg:v用ORDER BY子句改变游标中的执行顺序 --声明名称为cursor_order的游标,对fruits表中的记录按照价格字段降序排列:
eg:v使用游标将学号为4的学生姓名改为“二师兄”
eg:v删除学号为4的学生信息