1.1 掌握触发器的基本知识
触发器对表进行插入、更新、删除的时候会自动执行的特殊存储过程。触发器一般用在check约束更加复杂的约束上面。触发器和普通的存储过程的区别是:触发器是当对某一个表进行操作。诸如:update、insert、delete这些操作的时候,系统会自动调用执行该表上对应的触发器。SQL Server 2005中触发器可以分为两类:DML触发器和DDL触发器,其中DDL触发器它们会影响多种数据定义语言语句而激发,这些语句有create、alter、drop语句。
DML触发器分为:
- after触发器(之后触发)
a、 insert触发器
b、 update触发器
c、 delete触发器
- instead of 触发器 (之前触发)
after触发器要求只有执行某一操作insert、update、delete之后触发器才被触发,且只能定义在表上。而instead of触发器表示并不执行其定义的操作(insert、update、delete)而仅是执行触发器本身。既可以在表上定义instead of触发器,也可以在视图上定义。
触发器有两个特殊的表:插入表(instered表)和删除表(deleted表)。这两张是逻辑表也是虚表。有系统在内存中创建者两张表,不会存储在数据库中。而且两张表的都是只读的,只能读取数据而不能修改数据。这两张表的结果总是与被改触发器应用的表的结构相同。当触发器完成工作后,这两张表就会被删除。Inserted表的数据是插入或是修改后的数据,而deleted表的数据是更新前的或是删除的数据。
1.2 掌握游标的基本知识
游标(Cursor)它使用户可逐行访问由SQL Server返回的结果集。使用游标(cursor)的一个主要的原因就是把集合操作转换成单个记录处理方式。用SQL语言从数据库中检索数据后,结果放在内存的一块区域中,且结果往往是一个含有多个记录的集合。游标机制允许用户在SQL server内逐行地访问这些记录,按照用户自己的意愿来显示和处理这些记录。
游标的优点:
- 允许程序对由查询语句select返回的行集合中的每一行执行相同或不同的操作,而不是对整个行集合执行同一个操作
- 提供对基于游标位置的表中的行进行删除和更新的能力。
- 游标实际上作为面向集合的数据库管理系统(RDBMS)和面向行的程序设计之间的桥梁,使这两种处理方式通过游标沟通起来。
游标的生命周期包含有五个阶段:声明游标、打开游标、读取游标数据、关闭游标、释放游标。
a、定义游标
declare cursor_name --游标名称
cursor [local | global] --全局、局部
[forward only | scroll] --游标滚动方式
[read_only | scroll_locks | optimistic] --读取方式
for select_statements --查询语句
[for update | of column_name ...] --修改字段
b、打开游标
open cursor_name;
游标打开后,可以使用全局变量@@cursor_rows显示读取记录条数
c、检索游标
fetch cursor_name;
检索方式如下:
- fetch first; 读取第一行
- fetch next; 读取下一行
- fetch prior; 读取上一行
- fetch last; 读取最后一行
- fetch absolute n; 读取某一行;如果n为正整数,则读取第n条记录; 如果n为负数,则倒数提取第n条记录; 如果n为,则不读取任何记录;
- fetch pelative n;如果n为正整数,则读取上次读取记录之后第n条记录;如果n为负数,则读取上次读取记录之前第n条记录;如果n为,则读取上次读取的记录
d、关闭游标
游标打开后,服务器会专门为游标分配一定的内存空间存放游标操作的数据结果集,同时使用游标也会对某些数据进行封锁。所以游标一旦用过,应及时关闭,避免服务器资源浪费。
--关闭游标语法
close [ Global ] cursor_name | cursor_variable_name
--关闭游标
close cursor_name
e、删除游标
删除游标,释放资源
--释放游标语法
deallocate [ Global ] cursor_name | cursor_variable_name
--释放游标
deallocate cursor_name
完整游标示例:
--存储读取的值
declare @id int,
@name nvarchar(20),
@age varchar(20);
declare cursor_stu
cursor scroll for
select id, name,age from student;
--打开游标
open cursor_stu;
--读取第一条记录
fetch first from cursor_stu into @id, @name, @age;
--循环读取游标记录
print '读取的数据如下:';
--全局变量 0-FETCH 语句成功。-1 FETCH 语句失败或此行不在结果集中。-2被提取的行不存在
while (@@fetch_status = 0)
begin
print '编号:' + convert(char(5), @id) + ', 名称:' + @name + ', 类型:' + @age;
--继续读取下一条记录
fetch next from cursor_stu into @id, @name, @age;
end
close cursor_stu --关闭游标
deallocate cursor_stu --删除游标