SQL的游标使用规则详解和范例
MS-SQL的游标是一种临时的数据库对象,既对可用来旋转储存在系统永久表中的数据行的副本,也可以指向储存在系统永久表中的数据行的指针。
游标为您提供了在逐行的基础上而不是一次处理整个结果集为基础的操作表中数据的方法。1.如何使用游标
1)定义游标语句Declare <游标名> Cursor For
2)创建游标语句Open <游标名>
3)提取游标列值、移动记录指针Fetch <列名列表> From <游标名> [Into <变量列表>] 4)使用@@Fetch_Status利用While循环处理游标中的行
5)删除游标并释放语句Close <游标名>/Deallocate <游标名>
6)游标应用实例
--定义游标
Declare cur_Depart Cursor
For Select cDeptID,cDeptName From Department into @DeptID,@DeptName
--打开游标
Open cur_Depart
--移动或提取列值
Fetch From cur_Depart into @DeptID,@DeptName
--利用循环处理游标中的列值
While @@Fetch_Status=0
Begin
Print @DeptID,@DeptName
Fetch From cur_Depart into @DeptID,@DeptName
End
--关闭/释放游标
Close cur_Depart
Deallocate cur_Depart
简单的过程:
定义游标
DECLARE CustomerCursor CURSOR FOR
SELECT acct_no,name,balance
FROM customer
WHERE province="北京";
打开游标
OPEN CustomerCursor;
提取数据--设置循环
lb_continue=True
ll_total=0
DO WHILE lb_continue
FETCH CustomerCursor
INTO:ls_acct_no, :ls_name, :ll_balance;
If sqlca.sqlcode=0 Then
ll_total+=ll_balance
Else
lb_continue=False
End If
LOOP
--关闭游标
CLOSE CustomerCursor;
Deallocate CustomerCursor
2.语句的详细及注意
1)定义游标语句
Declare <游标名> [Insensitive] [Scroll] Cursor
For
Insensitive DBMS创建查询结果集数据的临时副本(而不是使用直接引用数据库表中的真实数据行中的列)。游标是Read Only,也就是说不能修改其内容或底层表的内容;
Scroll 指定游标支持通过使用任意Fetch 选项(First Last Prior Next Relative Absolute)选取它的任意行作为当前行。如果此项省略,则游标将只支持向下移动单行(即只支持游标的Fetch Next);
Select语句定义游标结果集的标准SELECT 语句。在游标声明的
Read Only 防止使用游标的用户通过更新数据或删除行改变游标的内容;
Update 创建可更新游标且列出值能被更新的游标列。如果子句中列入了任意列,则只有被列入的列才能被更新。如果Declare Cursor语句中只指定的UPDA TE(没有列名列表),则游标将允许更新它的任何或所有列。
Declare cur_Depart Cursor
For Select * From Department For Update OF cDeptID,cDeptName
2)提取游标列值、移动记录指针语句
Fetch [Next | Prior | First | Last | {Absolute <行号>} | {Relative <行号>}]
From <游标名> [Into <变量列表……>]
每次执行Fetch语句时,DBMS移到游标中的下一行并把游标中的列值获取到Into中列出的变量中。因此Fetch语句的Into子句中列出的变量必须与游标定义中Select 语句中的列表的类型与个数相对应;仅当定义游标时使用Scroll参数时,才能使用Fetch语句的行定位参数(First、Last、Prior、Next、Relative、Absolute);如果Fetch语句中不包括参数Next | Prior | First | Last,DBMS将执行默认的Fetch Next;
Next 向下、向后移动一行(记录);
Prior 向上、向前移动一行(记录);
First 移动至结果集的第一行(记录);
Last 移动至结果集的最后一行(记录);
Absolute n 移动到结果集中的第n行。如果n是正值,DBMS从结果集的首部向后或向下移动至第n行;如果n是负数,则DBMS从结果集的底部向前或向上移动n行;Fetch Absolute 2 From cur_Depart Into @DeptID,@DeptName
Relative n 从指针的当前位置移动n行。如果n是正值,DBMS将行指针向后或向下移动至第n行;如果n是负数,则DBMS将行指针向前或向上移动n行;
Fetch Relative 2 From cur_Depart Into @DeptID,@DeptName
3)基于游标的定位DELETE/UPDATE语句
如果游标是可更新的(也就是说,在定义游标语句中不包括Read Only参数),就可以用游标从游标数据的源表中DELETE/UPDATE行,即DELETE/UPDATE基于游标指针的当前位置的操作;
举例:
--删除当前行的记录
Declare cur_Depart Cursor
For Select cDeptID,cDeptName From Department into @DeptID,@DeptName
Open cur_Depart
Fetch From cur_Depart into @DeptID,@DeptName
Delete From Department Where CURRENT OF cur_Depart
--更新当前行的内容
Declare cur_Depart Cursor
For Select cDeptID,cDeptName From Department into @DeptID,@DeptName
Open cur_Depart
Fetch From cur_Depart into @DeptID,@DeptName
Update Department Set cDeptID=’2007’ + @DeptID Where CURRENT OF cur_Depart 3.游标使用技巧及注意
1)利用Order By改变游标中行的顺序。此处应该注意的是,只有在查询的中Select 子句中出现的列才能作为Order by子句列,这一点与普通的Select语句不同;
2)当语句中使用了Order By子句后,将不能用游标来执行定位DELETE/UPDATE语句;如何解决这个问题,首先在原表上创建索引,在创建游标时指定使用此索引来实现;例如:Declare cur_Depart Cursor
For Select cDeptID,cDeptName From Department With INDEX(idx_ID)
For Update Of cDeptID,cDeptName
通过在From子句中增加With Index来实现利用索引对表的排序;
3)在游标中可以包含计算好的值作为列;
4)利用@@Cursor_Rows确定游标中的行数
4.使用系统过程管理游标
在建立一个游标之后,便可利用系统过程对游标进行管理管理,游标的系统过程主要有以下几个:sp_cursor_list、sp_describe_cursor、sp_describe_cursor_tables 、sp_describe_cursor_columns。
1)sp_cursor_list 显示在当前作用域内的游标及其属性。其命令格式为:
">sp_cursor_list [ @cursor_return = ] cursor_variable_name OUTPUT,
[ @cursor_scope = ] cursor_scope
参数:
·[@cursor_return =] cursor_variable_name OUTPUT:声明的游标变量的名称。cursor_variable_name 的数据类型为cursor,没有默认值。游标是可滚动的、动态的只读游标。
·[@cursor_scope =] cursor_scope:指定要报告的游标级别。cursor_scope 的数据类型为int,没有默认值,可以是下列值中的一个。
提示:由于sp_cursor_list是一个含有游标类型变量@cursor_return,且有OUTPUT保留字的系统过程,游标变量@cursor_return中的结果集与pub_cur游标中的结果集是不同的。
2)sp_describe_cursor 报告服务器游标的特性。
sp_describe_cursor [ @cursor_return = ] output_cursor_variable OUTPUT
{ [ , [ @cursor_source = ] N''local''
, [ @cursor_identity = ] N''local_cursor_name'' ]
| [ , [ @cursor_source = ] N''global''
, [ @cursor_identity = ] N''global_cursor_name'' ]
| [ , [ @cursor_source = ] N''variable''
, [ @cursor_identity = ] N''input_cursor_variable'' ]
}
参数:
·[@cursor_return =] output_cursor_variable OUTPUT:声明游标变量的名称,该变量接收游标输出。output_cursor_variable 的数据类型为cursor,没有默认值。调用sp_describe_cursor 时,不能与任何游标相关联。返回的游标是可滚动的动态只读游标。·[@cursor_source =] { N''local'' | N''global'' | N''variable'' }:指定是使用本地游标的名称、全局游标的名称、还是游标变量的名称来指定当前正在对其进行报告的游标。参数是nvarchar(30)。
·[@cursor_identity =] N''local_cursor_name'']:由具有LOCAL 关键字或默认设置为LOCAL 的DECLARE CURSOR 语句创建的游标的名称。local_cursor_name 的数据类型为nvarchar(128)。
·[@cursor_identity =] N''global_cursor_name'']:由具有GLOBAL 关键字或默认
设置为GLOBAL 的DECLARE CURSOR 语句创建的游标的名称。也可以是由ODBC 应用程序打开然后通过调用SQLSetCursorName 对游标命名的API 服务器游标的名称。global_cursor_name 的数据类型为nvarchar(128)。
·[@cursor_identity =] N''input_cursor_variable'']:与开放游标相关联的游标变量的名称。input_cursor_variable 的数据类型为nvarchar(128)。
提示:sp_descride_cursor_tables和sp_describe_cursor_columms的命令格式与sp_describe_cursor的命令格式一样。
5.游标种类
MS SQL SERVER 支持三种类型的游标:Transact_SQL 游标,API 服务器游标和客户游标。1)Transact_SQL 游标Transact_SQL 游标是由DECLARE CURSOR 语法定义、主要用在Transact_SQL 脚本、存储过程和触发器中。Transact_SQL 游标主要用在服务器上,由从客户端发送给服务器的Transact_SQL 语句或是批处理、存储过程、触发器中的Transact_SQL 进行管理。Transact_SQL 游标不支持提取数据块或多行数据。
2)API 游标API 游标支持在OLE DB,ODBC 以及DB_library 中使用游标函数,主要用在服务器上。每一次客户端应用程序调用API 游标函数,MS SQL SEVER 的OLE DB 提供者、ODBC驱动器或DB_library 的动态链接库(DLL)都会将这些客户请求传送给服务器以对API游标进行处理。
3)客户游标客户游标主要是当在客户机上缓存结果集时才使用。在客户游标中,有一个缺省的结果集被用来在客户机上缓存整个结果集。客户游标仅支持静态游标而非动态游标。由于服务器游标并不支持所有的Transact-SQL 语句或批处理,所以客户游标常常仅被用作服务器游标的辅助。因为在一般情况下,服务器游标能支持绝大多数的游标操作。
由于API 游标和Transact-SQL 游标使用在服务器端,所以被称为服务器游标,也被称为后台游标,而客户端游标被称为前台游标。在本章中我们主要讲述服务器(后台)游标。select count(id) from info
select * from info
--清除所有记录
truncate table info
declare @i int
set @i=1
while @i<1000000
begin
insert into info values(''Justin''+str(@i),''深圳''+str(@i))
set @i=@i+1
end
6.游标和游标的优点
在数据库中,游标是一个十分重要的概念。游标提供了一种对从表中检索出的数据进行操作的灵活手段,就本质而言,游标实际上是一种能从包括多条数据记录的结果集中每次提
取一条记录的机制。游标总是与一条T_SQL 选择语句相关联因为游标由结果集(可以是零条、一条或由相关的选择语句检索出的多条记录)和结果集中指向特定记录的游标位置组成。当决定对结果集进行处理时,必须声明一个指向该结果集的游标。如果曾经用 C 语言写过对文件进行处理的程序,那么游标就像您打开文件所得到的文件句柄一样,只要文件打开成功,该文件句柄就可代表该文件。对于游标而言,其道理是相同的。可见游标能够实现按与传统程序读取平面文件类似的方式处理来自基础表的结果集,从而把表中数据以平面文件的形式呈现给程序。
我们知道关系数据库管理系统实质是面向集合的,在MS SQL SERVER中并没有一种描述表中单一记录的表达形式,除非使用where 子句来限制只有一条记录被选中。因此我们必须借助于游标来进行面向单条记录的数据处理。
由此可见,游标允许应用程序对查询语句select 返回的行结果集中每一行进行相同或不同的操作,而不是一次对整个结果集进行同一种操作;它还提供对基于游标位置而对表中数据进行删除或更新的能力;而且,正是游标把作为面向集合的数据库管理系统和面向行的程序设计两者联系起来,使两个数据处理方式能够进行沟通。
触发器 一﹕触发器是一种特殊的存储过程﹐它不能被显式地调用﹐而是在往表中插入记录﹑更新记录或者删除记录时被自动地激活。所以触发器可以用来实现对表实施复杂的完整性约束。 二﹕SQL Server为每个触发器都创建了两个专用表﹕Inserted表和Deleted表。这两个表由系统来维护﹐它们存在于内存中而不是在数据库中。这两个表的结构总是与被该触发器作用的表的结构相同。触发器执行完成后﹐与该触发器相关的这两个表也被删除。Deleted表存放由于执行Delete或Update语句而要从表中删除的所有行。Inserted表存放由于执行Insert或Update语句而要向表中插入的所有行。 三﹕Instead of 和After触发器 SQL Server提供了两种触发器﹕Instead of 和After 触发器。 这两种触发器的差别在于他们被激活的操作﹕ Instead of触发器用于替代引起触发器执行的T-SQL语句。除表之外﹐Instead of 触发器也可以用于视图﹐用来扩展视图可以支持的更新操作。 After触发器在一个Insert,Update或Deleted语句之后执行﹐进行约束检查等动作都在After 触发器被激活之前发生。After触发器只能用于表。一个表或视图的每一个修改动作(insert,update和delete)都可以有一个instead of 触发器﹐一个表的每个修改动作都可以有多个After触发器。 INSTEAD OF触发器被用于更新那些没有办法通过正常方式更新的视图。通常不能在一个基于连接的视图上进行DELETE操作,可以编写一个INSTEAD OF DELETE触发器来实现删除。可以访问那些如果视图是一个真正的表时已经被删除的数据行,它将把删除的行存储在deleted临时表中。 本次练习将通过具体的例子介绍如何使用INSTEAD OF触发器,使读者掌握INSTEAD OF 触发器的使用方法。 向student表中插入数据时,检查学号是否存在于student表中,如存在则进行插入操作,否则就不插入,具体语句如下所示: CREATE TRIGGER [checkid] ON dbo.student INSTEAD OF insert AS IF NOT EXISTS(SELECT * FROM dbo.student WHERE ID=(SELECT ID FROM INSERTED)) BEGIN ROLLBACK TRANSACTION PRINT '要处理记录的学号不存在!' END ELSE BEGIN INSERT NTO dbo.student select * from inserted
数据库原理与应用 课程设计A报告 姓名:袁一帆学号:20121480 学院(系):管理学院专业:信息管理与信息系统
班级:12级信管1 班
襄阳迈博信息科技有限公司企业考勤管理系统 一、系统目标设计 1系统开发的总体任务是实现企业员工考勤管理的系统化、规范化、和自动化。 2能够和人事管理系统、工资管理系统相结合,真正实现企业高效、科学、现代化的员工管理。 二、开发实际思想 1尽量采用公司现有软硬件环境,及先进的管理系统开发方案,从而达到充分利用公司现有资源,提高系统开发水平和应用效果的目的。 2员工考勤管理系统能够和考勤机相连接,从而完成自动、高效、科学的考勤信息输入。 3系统采用模块化程序设计方法,既便与系统功能的各种组合和修该,又便于未参与开发的技术维护人员补充、维护。 系统应具备数据库维护功能,即使根据用户需求进行数据的添加、删除、修改、被分等操作。 系统需求分析 1 考勤管理涉及企业人事管理的多个方面,如员工职务升迁、工资发放、奖金发放、员工医疗保险发放等等。本利自重的考勤管理系统需要完成功能主要有以下几点。 2 员工考勤信息处理。该莫完成员工考勤情况的输入、修改等操作。如果企业内有考勤机,可以将它的输出处理后,形成考勤管理系统考勤模块的
输入。 3 企业缺勤类型的设定。 4 企业考勤统计。该模块可对某个员工进行考勤情况的统计,生成统计报表。 5 缺勤时间,缺勤类型对工资的影响 6 缺勤时间,缺勤类型对升职的影响 数据字典 数据项 表1 名称员工编号 说明每个员工拥有唯一的编号 类型字符型 长度 4 有关数据存储员工基本信息存储 表2 名称员工姓名
信息学部 实验报告 课程名称:网络数据库 实验名称:游标、存储过程、触发器实验类型:□验证性□综合性□设计性实验日期: 学生姓名: 学号: 班级: 专业:信息管理与信息系统学部:信息学部 指导教师:康瑶 成绩: 评语: 2015 年—2016 年第二学期
实验五:游标、存储过程、触发器 实验内容: 在scott方案下完成如下实验内容: 1、用显式游标编写程序,程序的功能是:计算每一个部门的平均工资,输出部门名称dname及平均工资avg_sal。(利用scott方案下的emp表及dept表) 2、编写一个存储过程,此过程的功能是将scott方案下的emp表中工资大于1000的ename,job,sal的30%,comm插入表bonus中,要求用显示游标完成数据插入操作,然后编写PL/SQL程序执行此存储过程,并显示最终结果。 3、在scott方案下定义一个存储过程使用游标方式,根据emp表员工编号参数, 查询并打印该员工的下属的姓名,职位,工资等信息。 4、创建存储过程GetGrade(v_empno),查询指定员工的工资等级。工资小于等于3000,等级为“低”;工资大于3000,小于5000,等级为”中”;工资大于等于5000,等级为高。并执行该存储过程。 5、创建存储过程UpdateWage,查询指定员工的工资,如果工资小于3000, 则加200工资,并提示信息“XX号员工工资已更新。”,如果工资大于3000,则提示信息“XX号员工工资为XXX,已达到规定标准。” 6、定义一个函数,根据部门编号参数,查询出该部门的员工总数,并作为参数输出。 7、定义触发器MyTrigger,当表UserType中TypeId列的值发生变化时,自动更新表Users中的UserType列的值,从而保证数据的完整性: 8、创建触发器MyTrigger,它的作用是当表departments中的记录被删除后,自动删除表employees中的对应的员工记录,从而保证数据的完整性。 实验步骤(图文并茂):
oracle11g 游标: 1. 当在PL/SQL中使用SQL语句时,Oracle会为其分配上下文区域,这是一段 私有的内存区域,用于暂时保存SQL语句影响到的数据。游标是指向这段内存区域的指针。 2. Oracle中主要有两种类型的游标: (1) 隐式游标:所有的DML语句和PL/SQL SELECT 语句都有; (2) 显式游标:由开发人员声明和控制。 3. 可以使用的游标属性包括四种:%ROWCOUNT、%FOUND、%NOTFOUND、 %ISOPEN,这四种属性对于显式游标和隐式游标都有用,但是含义和使用方法略有不同。游标在使用属性时,需要以游标名称作为前缀,以表明该属性是哪个游标的,隐式游标没有名称,所以在使用隐式游标时采取了统一的一个名称SQL。 4. 在PL/SQL中的SELECT语句只能且必须取出一行数据,取出多行或者零行都 被认为是异常,所以在对多行数据进行操作时,必须使用显式游标来实现。 5. 使用显式游标的步骤: (1)声明游标:CURSOR cursor_name is select_statement; (2)打开游标:OPEN cursor_name; (3)取游标中的数据:FETCH cursor_name INTO variable1,variable2,...; (4)关闭游标:CLOSE cursor_name; 6.用变量接收游标中的数据 sql> declare v_name emp.ename%TYPE; v_sal emp.sal%TYPE; cursor emp_cursor is select ename,sal from emp where deptno=10; begin open emp_cursor; loop fetch emp_cursor into v_name,v_sal; exit when emp_cursor%NOTFOUND; dbms_output.put_line(v_name || ‘的薪水是’ || v_sal);
SQL触发器实例讲解 2008-11-27 16:16:45| 分类:PROCEDURE | 标签:|字号大中小订阅 SQL触发器实例1 定义:何为触发器?在SQL Server里面也就是对某一个表的一定的操作,触发某种条件,从而执行的一段程序。触发器是一个特殊的存储过程。 常见的触发器有三种:分别应用于Insert , Update , Delete 事件。 我为什么要使用触发器?比如,这么两个表: Create Table Student( --学生表 StudentID int primary key, --学号 .... ) Create Table BorrowRecord( --学生借书记录表 BorrowRecord int identity(1,1), --流水号 StudentID int , --学号 BorrowDate datetime, --借出时间 ReturnDAte Datetime, --归还时间 ... ) 用到的功能有: 1.如果我更改了学生的学号,我希望他的借书记录仍然与这个学生相关(也就是同时更改借书记录表的学号); 2.如果该学生已经毕业,我希望删除他的学号的同时,也删除它的借书记录。 等等。 这时候可以用到触发器。对于1,创建一个Update触发器: Create Trigger truStudent On Student --在Student表中创建触发器 for Update --为什么事件触发 As --事件触发后所要做的事情 if Update(StudentID) begin Update BorrowRecord Set StudentID=i.StudentID
删除SQL Server 的特定实例 若要删除SQL Server 的特定实例,请按照下列步骤操作: 1.找到并删除%drive%:\Program Files\Microsoft SQL Server\MSSQL\Binn 文件 夹,其中%drive%是要删除的SQL Server 实例的位置。 2.找到以下注册表项: o HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MSSQLServer 注意:如果要删除默认实例,则必须删除除Client项以外的所有项。 o HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SQL Server 必须使用Regedt32.exe 来编辑要删除的实例的InstalledInstances 值。默认实例的显示名称为MSSQLSERVER,而命名实例的显示名称则为给该 实例指定的名称。 注意:不能使用Regedit.exe 编辑该值;您必须使用Regedt32.exe。 注意:如果这是SQL Server 2000 的群集实例,请为群集中的每个节点重复执行这些步骤。 删除SQL Server 的所有已知实例 若要删除SQL Server 的所有已知实例,请按照下列步骤操作: 1.找到并删除%drive%:\Program Files\Microsoft SQL Server\MSSQL\Binn 文件 夹。 2.找到并删除以下注册表项: o HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MSSQLServer o HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SQL Server 3.找到并删除以下注册表项: o HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\MSSQL Server o HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SQLSER VERAGENT o HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\MSSQL ServerADHelper 4.步骤3 中的三个注册表项对应于Microsoft SQL Server 2000 的默认实例。命名实例 对应的注册表项与步骤 3 中列出的注册表项类似,但后面带有$instance_name,因
SqlServer触发器的原理及案例合理的选用触发器会让你的系统更高效 2010 Ssc
目录 第1章何为触发器 (3) 1.1 触发器的'本质' (3) 1.2 这样做带来的'功能': (3) 1.3 触发器的作用 (3) 1.4 说明: (3) 第2章对触发器3种操作的分析 (4) 2.1 创建触发器 (4) 2.2 学习案例 (5) 2.2.1 建立表 (5) 2.2.2 触发器练习1 (5) 2.2.3 触发器练习2: (6) 第3章图形化操作触发器 (7) 3.1 查看触发器情况 (7) 第4章触发器中的变量操作 (11) 第5章SQL触发器语法参考 (11)
第1章何为触发器 1.1触发器的'本质' 触发器是一种特殊的存储过程,它不能被显式地调用,而是在往表中插入记录、更改记录或者删除记录时,当事件发生时,才被自动地激活。 1.2这样做带来的'功能': 触发器可以用来对表实施复杂的完整性约束,保持数据的一致性,当触发器所保护的数据发生改变时,触发器会自动被激活,响应同时执行一定的操作(对其它相关表的操作),从而保证对数据的不完整性约束或不正确的修改。触发器可以查询其它表,同时也可以执行复杂的T-SQL语句。触发器和引发触发器执行的命令被当作一次事务处理,因此就具备了事务的所有特征。 注意:'事务具备什么特征?在触发器中的作用?' 如果发现引起触发器执行的T-SQL语句执行了一个非法操作,比如关于其它表的相关性操作,发现数据丢失或需调用的数据不存在,那么就回滚到该事件执行前的SQL SERVER数据库状态。 1.3触发器的作用 触发器可以对数据库进行级联修改,这一点刚才已经说过了。需要说明的是:'触发器和约束的关系和区别' (1)一般来说,使用约束比使用触发器效率更高。 (2)同时,触发器可以完成比CHECK约束更复杂的限制。 1.4说明: 1.与CHECK约束不同,在触发器中可以引用其它的表。 2.触发器可以发现改变前后表中数据的不一致,并根据这些不同来进行相应的操作。
SQL Code 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 Declare @barCode varchar(50)--声明变量用于存放游标结果 DECLARE CsrName CURSOR FOR--声明游标 select barCode from eachBook --游标数据来源 BEGIN OPEN CsrName --打开游标 FETCH FROM CURSUBOK INTO @barCode--获得来源的一行记录放入变量 WHILE @@FETCH_STATUS = 0 BEGIN -----------------------------------------------------针对每个结果做的操作 print @barcode ----------------------------------------------------------------------------End FETCH NEXT FROM CsrName INTO @barCode --处理下一行数据 CLOSE CsrName --游标用完了要关掉 END 总结:一般sql语句是面向集合的,游标是面向集合里面的行的,相当于获取一行数据->处理->获得下一行数据->处理这样一个循环。能不用游标就尽量不要用游标,性能很烂 --两种触发器,after为表sql语句执行之后操作,INSTEAD OF为之前操作 create trigger tgr_name--创建触发器 on classes --在classes表上 for insert--当classes表插入数据是触发as里面的操作(for 有after默认值,所以是sql 语句执行完了执行) --,有insert、update、delete三种操作类型。 as declare @id int;--定义变量用来临时存放数据 select @id = id from inserted; --在inserted表中查询已经插入记录信息,update就有个updated表,deleted就是deleted表 print '刚刚插入的记录的ID是'+@id; GO
--建立触发器,显示修改人数 create trigger d1 on jun for insert,update as select '你正在修改数据' declare @a varchar(20) select @a=str(@@rowcount)+'个学生被修改' select @a select * from jun return insert into jun(爱好) values('跑步') update jun set 爱好='打球' where 学号<='103' --建立触发器,当男生人数在6个以内可以加入,否则不能加入 create trigger i1 on zg for insert as if((select count(性别) from zg where 性别='男')>6) select '不能插入,男生人数已满。' else select'插入成功' select * from zg insert into zg(学号,姓名,性别) values(20100636,'江渝','男') --建立触发器,如果语文成绩在200以内可以修改,否则不能修改 create trigger u1 on zg for update as if((select max(语文) from zg )>200) begin select '你不能修改' rollback end else select '修改成功' select * from zg update zg set 语文=语文+10 where 姓名='唐荣强' update zg set 语文=语文-20 where 姓名='张军' update zg set 语文=语文+30 where 姓名='张军'
创建触发器 为了演示触发器的功能,下面再引入一个简易仓库管理的例子。在采购配件前,必须首先制定采购计划(如采购计划表 PlanA),然后交由采购员采购,采购回来后,要将配件入库,入库时,除了要修改入库表(配件入库表 InStock)外,还要修改配件库存表(仓库库存表 Stock),还要修改采购计划表(采购计划表 PlanA),因为要修改实际完成的采购量(FinishQty)。三个数据表如下: 采购计划表 PlanA 备件入库表 InStock 备件库存表 Stock 给计划表追加如下数据 一、用企业管理器创建触发器 例1:对备件入库InStock表建立一个插入触发器utr_InStockIns,其功能为:备件入库时,除了要将入库数据追加到备件入库表(InStock)外,还要修改计划表(PlanA)中对应计划号的完成数量(增加FinishQty)和备件库存表(Stock)中对应备件代码的库存数量(StockQty)。 注:同企业管理器创建的触发器
例2:对备件入库表建立一个删除触发器utr_InStockDel,其功能为:删除备件入库中的记录时,除了要删除入库表(InStock)的记录外,还要修改计划表(PlanA)中对应计划号的完成数量(减少FinishQty),还要删除备件库存表(Stock)中对应备件代码的记录。
例3:对备件入库表建立一个更改除触发器utr_InStockUpt,其功能为:更改备件入库中的记录时,除了要更改入库表(InStock)的记录外,还要更改备件库存表(Stock)中对应备件代码的数据,同时,还要更改计划表(PlanA)中对应计划号的完成数量(FinishQty)。
SQL触发器全过程 第一、概述 一:触发器是一种特殊的存储过程,它不能被显式地调用,而是在往表中插入记录﹑更新记录或者删除记录时被自动地激活。所以触发器可以用来实现对表实施复杂的完整性约`束。 二: SQL Server为每个触发器都创建了两个专用表:Inserted表和Deleted 表。这两个表由系统来维护,它们存在于内存中而不是在数据库中。这两个表的结构总是与被该触发器作用的表的结构相同。触发器执行完成后,与该触发器相关的这两个表也被删除。 Deleted表存放由于执行Delete或Update语句而要从表中删除的所有行。 Inserted表存放由于执行Insert或Update语句而要向表中插入的所有行。 三:instead of 和 After触发器 SQL Server2000提供了两种触发器:Instead of 和After 触发器。这两种触发器的差别在于他们被激活的同: Instead of触发器用于替代引起触发器执行的T-SQL语句。除表之外,Instead of 触发器也可以用于视图,用来扩展视图可以支持的更新操作。 After触发器在一个Insert,Update或Deleted语句之后执行,进行约束检查等动作都在After触发器被激活之前发生。After触发器只能用于表。
一个表或视图的每一个修改动作(insert,update和delete)都可以有一个instead of 触发器,一个表的每个修改动作都可以有多个After触发器。 四:触发器的执行过程 如果一个Insert﹑update或者delete语句违反了约束,那幺After触发器不会执行,因为对约束的检查是在After触发器被激动之前发生的。所以After 触发器不能超越约束。 Instead of 触发器可以取代激发它的操作来执行。它在Inserted表和Deleted表刚刚建立,其它任何操作还没有发生时被执行。因为Instead of 触发器在约束之前执行,所以它可以对约束进行一些预处理。 五:使用T-SQL语句来创建触发器 基本语句如下: create trigger trigger_name on {table_name | view_name} {for | After | Instead of } [ insert, update,delete ] as sql_statement
数据库设计的案例分析 一、教学管理 1. 基本需求 某学校设计学生教学管理系统。学生实体包括学号、姓名、性别、生日、民族、籍贯、简历、登记照,每名学生选择一个主修专业,专业包括专业编号和名称,一个专业属于一个学院,一个学院可以有若干个专业。学院信息要存储学院号、学院名、院长。教学管理还要管理课程表和学生成绩。课程表包括课程号、课程名、学分,每门课程由一个学院开设。学生选修的每门课程获得一个成绩。 设计该教学管理的ER模型,然后转化为关系模型。 若上面的管理系统还要管理教师教学安排,教师包括编号、姓名、年龄、职称,一个教师只能属于一个学院,一名教师可以上若干门课程,一门课程可以有多名老师来上,每个教师所上的每门课都有一个课堂号和课时数。试修改上题的ER模型,将教师教学信息管理增加进去。
2. 参考设计: 图一教学管理ER图 由ER模型转换的关系模型是: 学生(学号,姓名,性别,生日,民族,籍贯,专业号,简历,登记照)专业(专业号,专业,专业类别,学院号) 学院(学院号,学院,院长) 课程(课程号,课程名,学分,学院号) 成绩(学号,课程号,成绩) (题目分析:本题中有学生、专业、学院、课程四个实体。一个学生只有一个主修专业,学生与专业有多对一的联系;一个专业只由一个学院开设,一门课程只由一个学院开设,学院与专业、学院与课程都是一对多的联系;学生与课程有多对多的联系。 在转换为关系模型时,一对多的联系都在相应的多方实体的关系中增加一个外键。) 增加教师,ER图如下。
图二有教师实体的教学管理ER图 3. 物理设计 基于Access的数据库结构设计如下。 指定数据库文件的名称,并为设计好的关系模型设计表结构。 数据库文件保存在“E:\教学管理\”文件夹中,数据库文件名:教学管理.MDB。 表包括:学院、专业、学生、课程、成绩单。对应表结构如表1-2至表1-6所示。 表1-1 学院 表1-2 专业 表1-3 学生
触发器 ?触发器是一种特殊类型的存储过程,它在指定的表中的数据发生变化(INSERT、 UPDATE 或DELETE)时自动执行 ?触发器可以查询其它表,并可以包含复杂的Transact-SQL 语句 ?主要用于强制复杂的业务规则或要求 优点 ?自动执行 ?实现相关表层叠修改,实现多个表之间数据的一致性和完整性 ?实现比check约束更复杂的限制,可以引用其他表中的列 触发器的类型 ?AFTER触发器:在数据变动(INSERT、UPDATE、DELETE操作)完成后激发,只能在表 上定义,同一个表中可以有多个AFTER触发器 ?INSTEAD OF触发器:在数据变动以前被激发,并取代变动数据(INSERT、UPDATE、 DELETE操作),转而去执行触发器定义的操作,可以定义在表或视图上,每个update、insert和delete语句最多可以定义一个INSTEAD OF触发器。 创建触发器 ?CREATE TRIGGER trigger_name ON { table | view } [ WITH ENCRYPTION ] { { FOR | AFTER | INSTEAD OF } { [ INSERT ] [ , ] [ UPDATE ] [, ][DELETE]} AS sql_statement [...n ] } 触发器示例: ?CREATE TRIGGER reminder ON titles FOR INSERT, UPDATE AS RAISERROR (50009, 16, 10) 指定触发器何时激发 ?AFTER 触发器在触发操作(INSERT、UPDATE 或DELETE)后和处理完任何约束后激 发。可通过指定AFTER 或FOR 关键字来请求AFTER 触发器。 ?INSTEAD OF 触发器代替触发动作进行激发,并在处理约束之前激发。 ?对于每个触发操作(UPDATE、DELETE 和INSERT),每个表或视图只能有一个 INSTEAD OF 触发器。而一个表对于每个触发操作可以有多个AFTER 触发器。 触发器示例: create TRIGGER reminder ON titles FOR INSERT, delete,update AS --修改操作 if (select count(*) from inserted) > 0 and (select count(*) from deleted) >0 begin RAISERROR ('修改成功', 16, 10) end
SQL触发器实例讲解 SQL 资料2009-07-23 14:44:07 阅读6072 评论9 字号:大中小订阅 定义:何为触发器?在SQL Serv er里面也就是对某一个表的一定的操作,触发某种条件,从而执行的一段程序。触发器是一个特殊的存储过程。 常见的触发器有三种:分别应用于Insert , Update , Delete 事件。 我为什么要使用触发器?比如,这么两个表: Create Table Student( --学生表 StudentID int primary key, --学号 .... ) Create Table BorrowRecord( --学生借书记录表 BorrowRecord int identity(1,1), --流水号 StudentID int , --学号 BorrowDate datetime, --借出时间 ReturnDAte Datetime, --归还时间 ... ) 用到的功能有: 1.如果我更改了学生的学号,我希望他的借书记录仍然与这个学生相关(也就是同时更改借书记录表的学号); 2.如果该学生已经毕业,我希望删除他的学号的同时,也删除它的借书记录。 等等。 这时候可以用到触发器。对于1,创建一个Update触发器: Create Trigger truStudent On Student --在Student表中创建触发器 f or Update --为什么事件触发 As --事件触发后所要做的事情 if Update(StudentID) begin Update BorrowRecord Set StudentID=i.StudentID From BorrowRecord br , Deleted d ,Inserted i --Deleted和Inserted临时表 Where br.StudentID=d.StudentID end
《数据库原理》实验报告要求 报告的主要内容 一、实验目的 根据各实验项目的实验目的撰写,具体在附件中给出。 二、实验环境 操作系统:Windows XP,数据库管理系统(DBMS):SQL Server2008 三、实验要求 根据各实验项目要求撰写,具体在附件中给出。 四、实验内容及完成情况 自己所完成的内容,进行了哪些操作、编写了哪些程序及执行后的结果,包括一些错误结果及解决办法等。 五、实验体会 具体要求 1、本实验属综合性实验,要使用学校统一的报告纸,附加纸张要挟在报告纸内并左侧装 订; 2、报告纸的封面要填写完整,项目要与实验日历中的项目完全一致,否则将返回重写; 3、报告第四项“实验内容及完成情况”中,只允许对操作结果和程序运行结果进行打印, 其余内容必须用钢笔或水性笔书写,报告要整洁; 4、严禁出现雷同报告,如果出现雷同,雷同报告的所有学生本次实验将作不及格或最低 分处理。如果出现不及格实验项目将取消考试资格。
实验目的及要求 实验三、存储过程及游标 实验目的: 综合运用程序设计和数据结构,使用游标完成具有较完整功能的存储过程。 实验要求: 根据所给的excel表格,完成实验内容。 说明:“招生表”中部分属性保存的是代码值,请按所给代码表完成如下要求。 1.使用SQL语句创建数据库,并在数据库中完成表的创建。(报告中要分析各个表的主键和外键是什么) 创建数据库studentManage
2.写一个存储过程,功能是查询所有招生信息。使用游标完成逐行输出,每行要有行号。 (在查询结果中,要求各类代码要替换成具体的文字信息,例如:政治面貌不要显示“01”,而要显示“中共党员”。)
sqlserver 触发器示例 1--检查当前触发器是否已存在 2IF exists(SELECT*FROM sysobjects WHERE xtype='TR'AND [name]='TR_INSERTUserInfo_LoginLog') 3--存在即删除该触发器 4DROP TRIGGER TR_INSERTUserInfo_LoginLog 5go 6--触发器创建在UserInfo表上当对UserInfo表执行INSERT操作后自动执行触发器中的SQL语句 7CREATE TRIGGER TR_INSERTUserInfo_LoginLog 8ON UserInfo 9FOR INSERT 10AS 11BEGIN 12--定义接受新建用户ID的参数 13DECLARE@userID VARCHAR(50); 14--查询INSERTED临时表获取新建用户ID 15SELECT@userID=UserID FROM Inserted 16--向用户登录日志表中添加新建用户登录日志 17INSERT INTO LoginLog VALUES(@userID,getDate()) 18END 19GO 20 21IF EXISTS(SELECT*FROM sysobjects WHERE xtype='TR'AND [name]='TR_Update_UserInfo_ManagerLog') 22DROP TRIGGER TR_Update_UserInfo_ManagerLog 23GO 24CREATE TRIGGER TR_Update_UserInfo_ManagerLog 25ON UserInfo 26FOR UPDATE 27AS 28--接受被更新用户信息的ID
SQLServer 触发器使用实例 触发器是一个特殊的存储过程。 常见的有三种:分别应用于Insert , Update , Delete 事件。 一、Trigger语法: create trigger tr_name on table/view {for | after | instead of } [update][,][insert][,][delete] [with encryption] as {batch | if update (col_name) [{and|or} update (col_name)] } 说明: 1 tr_name :名称 2 on table/view :触发器所作用的表。一个触发器只能作用于一个表 3 for 和after :同义 4 after 与instead of :sql 2000新增项目afrer 与instead of 的区别After 在触发事件发生以后才被激活,只可以建立在表上 Instead of 代替了相应的触发事件而被执行,既可以建立在表上也可以建立在视图上 5 insert、update、delete:激活触发器的三种操作,可以同时执行,也可选其一
6 if update (col_name):表明所作的操作对指定列是否有影响,有影响,则激活触发器。此外,因为delete 操作只对行有影响, 所以如果使用delete操作就不能用这条语句了(虽然使用也不出错,但是不能激活触发器,没意义)。 7 触发器执行时用到的两个特殊表:deleted ,inserted deleted 和inserted 可以说是一种特殊的临时表,是在进行激活触发器时由系统自动生成的,其结构与触发器作用的表结构是一 样的,只是存放的数据有差异。 二、实例: 实例1(注意这里的关联,条件是如何关联,update中set的值是与谁关联。这些都可以从【触发器的两个临时表:inserted、deleted】中得到答案) 比如,这么两个表: Create Table Student( --学生表 StudentID int primary key, --学号 StudentName varchar(50),姓名 ) Create Table BorrowRecord( --学生借书记录表 BorrowRecord int identity(1,1), --流水号 StudentID int , --学号 BorrowDate datetime, --借出时间
实验八数据库编程技术—游标、存储过程与触发器 一、实验目的 1.掌握游标的定义和使用方法 2.掌握存储过程的定义、执行和调用方法 3.掌握游标和存储过程的综合应用方法。 4.掌握触发器的创建和使用方法。 5.掌握游标和触发器的综合应用方法。 二、实验环境(实验的软件、硬件环境) 硬件:PC机软件:SQL2000 三、实验指导说明 请复习第八章数据库编程的相关知识,完成如下的实验内容。 四、实验内容 (1)利用游标查找所有女业务员的基本情况 (2)创建一游标,逐行显示表customer的记录,要求按 ‘客户编号’+‘-------’+‘客户名称’+‘-------’+‘客户地址’+‘-------------------’+‘客户电话’+‘----------’+‘客户邮编’+‘--------’格式输出,并且用while 结构来测试游标的函数@@Fetch_Status的返回值。 (3)利用游标修改orderMaster表中的Ordersum的值 (4)利用游标显示出orderMaster表中每一个订单所对应的明细数据信息。 (5)利用存储过程,给Employee表添加一条业务部门员工的信息。 (6)利用存储过程输出所有客户姓名、客户订购金额及其相应业务员的姓名 (7)利用存储过程查找某员工的员工编号、订单编号、销售金额。 (8)利用存储过程查找姓“李”并且职称为“职员”的员工的员工编号、订单编号、销售金额
(9)请使用游标和循环语句编写一个存储过程proSearchCustomer,根据客户编号,查询该客户的名称、地址以及所有与该客户有关的销售记录,销售记录按商品分组输出。 (10)设置一个触发器,该触发器仅允许dbo用户可以删除Employee表内数据,否则出错。 (11)在OrderMaster表中创建触发器,插入数据时要先检查Employee表中是否存在和Employee表同样值的业务员编号,如果不存在则不允许插入。 (12)级联更新:当更新customer表中的customerNo列的值时,同时更新OrderMaster表中的customerNo列的值,并且一次只能更新一行。 (13)对product表写一个UPDATE触发器。 五、实验步骤 请完成实验内容,并写出具体的实验步骤 六、思考题: 1.存储过程和触发器,函数的区别? 七、总结(实验过程的体会、心得和实验教与学之间还需改进的内容)
SQLServer-触发器使用实例
SQLServer 触发器使用实例 触发器是一个特殊的存储过程。 常见的有三种:分别应用于Insert , Update , Delete 事件。 一、Trigger语法: create trigger tr_name on table/view {for | after | instead of } [update][,][insert][,][delete] [with encryption] as {batch | if update (col_name) [{and|or} update (col_name)] } 说明: 1 tr_name :名称 2 on table/view :触发器所作用的表。一个触发器只能作用于一个表 3 for 和after :同义 4 after 与instead of :sql 2000新增项目afrer 与 instead of 的区别 After 在触发事件发生以后才被激活,只可以建立在表上 Instead of 代替了相应的触发事件而被执行,既可以建立在表上也可以建立在视图上
5 insert、update、delete:激活触发器的三种操作,可以同时执行,也可选其一 6 if update (col_name):表明所作的操作对指定列是否有影响,有影响,则激活触发器。此外,因为delete 操作只对行有影响, 所以如果使用delete操作就不能用这条语句了(虽然使用也不出错,但是不能激活触发器,没意义)。 7 触发器执行时用到的两个特殊表:deleted ,inserted deleted 和inserted 可以说是一种特殊的临时表,是在进行激活触发器时由系统自动生成的,其结构与触发器作用的表结构是一 样的,只是存放的数据有差异。 二、实例: 实例1(注意这里的关联,条件是如何关联,update中set的值是与谁关联。这些都可以从【触发器的两个临时表:inserted、deleted】中得到答案) 比如,这么两个表: Create Table Student( --学生表 StudentID int primary key, --学号 StudentName varchar(50),姓名 ) Create Table BorrowRecord( --学生借书记录表 BorrowRecord int identity(1,1), --流水号
上机6 游标和触发器 上机内容 1. 游标 2. 触发器 上机目标 1. 理解和应用游标 2. 理解和应用触发器 阶段1 指导部分 训练内容 创建和使用游标 需求说明 假定存在一张记录学员分数的表tb_score,其数据结构如图2.6.1所示。要求使用游标更新tb_score表中的rank字段,求出每位学员总分名次。 图2.6.1 学生分数表tb_score的数据结构 实现思路
(1)创建过程,命名为proc_upd_rank,在其中定义基于tb_score表的可更新游标,用于根据总分更新rank字段,如图2.6.2所示。 图2.6.2 创建使用游标的proc_upd_rank过程 (2)执行proc_upd_rank过程,实现更新rank字段并求名次的功能,如图2.6.3所示。 图2.6.3 执行proc_upd_rank过程并显示结果
练习部分(一) 需求说明 假定存在一张商品销售表tb_emp_sell,其数据结构如图2.6.4所示。要求通过此表生成一张如图2.6.5所示的报表。(注意:商品编号与雇员编号都是可变的。) 图2.6.4 商品销售表tb_emp_sell数据结构 图2.6.5 生成报表的数据结构 实现思路 (1)创建过程proc_emp_sell_report,在其中使用游标动态构造SQL语句,创建一张临时表,该表用于存放查询的结果。 CREATE OR REPLACE PROCEDURE proc_emp_sell_report AS BEGIN DECLARE v_temp INT;--定义临时变量 v_dyna_sql VARCHAR2(5000);--定义变量存放动态SQL语句
SQL Server 触发器 触发器是一种特殊类型的存储过程,它不同于之前的我们介绍的存储过程。触发器主要是通过事件进行触发被自动调用执行的。而存储过程可以通过存储过程的名称被调用。 ?什么是触发器 触发器对表进行插入、更新、删除的时候会自动执行的特殊存储过程。触发器一般用在check 约束更加复杂的约束上面。触发器和普通的存储过程的区别是:触发器是当对某一个表进行操作。诸如:update、insert、delete这些操作的时候,系统会自动调用执行该表上对应的触发器。SQL Server 2005中触发器可以分为两类:DML触发器和DDL触发器,其中DDL触发器它们会影响多种数据定义语言语句而激发,这些语句有create、alter、drop语句。 DML触发器分为: 1、after触发器(之后触发) a、insert触发器 b、update触发器 c、delete触发器 2、instead of 触发器(之前触发) 其中after触发器要求只有执行某一操作insert、update、delete之后触发器才被触发,且只能定义在表上。而instead of触发器表示并不执行其定义的操作(insert、update、delete)而仅是执行触发器本身。既可以在表上定义instead of触发器,也可以在视图上定义。 触发器有两个特殊的表:插入表(instered表)和删除表(deleted表)。这两张是逻辑表也是虚表。有系统在内存中创建者两张表,不会存储在数据库中。而且两张表的都是只读的,只能读取数据而不能修改数据。这两张表的结果总是与被改触发器应用的表的结构相同。当触发器完成工作后,这两张表就会被删除。Inserted表的数据是插入或是修改后的数据,而deleted 表的数据是更新前的或是删除的数据。