【文档说明】数据库对象管理课件.ppt,共(90)页,691.512 KB,由小橙橙上传
转载请保留链接:https://www.ichengzhen.cn/view-92429.html
以下为本文档部分文字说明:
数据库对象管理3.1索引3.2视图3.3存储过程3.4触发器23.1索引的概念3.1.1索引的概念3.1.2创建索引的优点与缺点3.1.3考虑建索引的列和不考虑建索引的列33.1.1索引的概念索引是为了加速对表中数据行的检索而
创建的一种分散的存储结构。索引是针对一个表而建立的,它是由数据页面以外的索引页面组成的。数据库中的索引是一个列表,在这个列表中包含了某个表中一列或者若干列值的集合,以及这些值的记录在数据表中的存储位置的物理地址。43.1.2索引的优、缺点1.创建索引的优点•
可以大大加快数据检索速度。•通过创建唯一索引,可以保证数据记录的唯一性。•在使用ORDERBY和GROUPBY子句进行检索数据时,可以显著减少查询中分组和排序的时间。•使用索引可以在检索数据的过程中使用优化隐藏器
,提高系统性能。•可以加速表与表之间的连接,这一点在实现数据的参照完整性方面有特别的意义。52.创建索引的缺点•①创建索引要花费时间和占用存储空间。创建索引需要占用存储空间,如创建聚簇索引需要占用的存储空间是数
据库表占用空间的1.2倍。在建立索引时,数据被复制以便建立聚簇索引,索引建立后,再将旧的未加索引的表数据删除。创建索引也需要花费时间。•②建立索引加快了数据检索速度,却减慢了数据修改速度。因为每当执行一次数据的插入、删除和更新操作,就要维护索引。修改的数据越多,涉及维
护索引的开销也就越大。如果将一些数据行插入到一个已经放满行的数据页面上,还必须将这个数据页面中最后一些数据移到下一个页面中去,这样,还必须改变索引页中的内容,以保持数据顺序的正确性。这就是对索引的维护。由于修改数据时要动态维护其索引,所以,对建立了索引的表执行修改操作
要比未建立索引的表执行修改操作所花的时间要长。因此,创建索引虽然可以加快数据查询的速度,但是却会减慢数据修改的速度。63.1.3考虑建索引的列和不考虑建索引的列1.考虑建索引的列如果在一个列上创建索引,该列就称为索引列。索引列中的值称为关
键字值。考虑建索引的列有如下这些:•①主键通常,检索、存取表是通过主键来进行的。因此,应该考虑在主键上建立索引。•②连接中频繁使用的列用于连接的列若按顺序存放,系统可以很快地执行连接。如外键,除用于实现参照完整性外,还经常用于进行表的连接。•③在某一范围内频繁搜索的列和按
排序顺序频繁检索的列。72.不考虑建索引的列建立索引需要产生一定的存储开销,在进行插入和更新数据的操作时,维护索引也要花费时间和空间,因此,没有必要对表中的所有列都建立索引。创建索引与否以及在哪些列上建立索引,要看建立索引和维护索引的代价与因建立索引所节省的时间相比哪个更合算。一般来说,如下一些
列不考虑建立索引:•①很少或从来不在查询中引用的列,因为系统很少或从来不根据这个列的值去查找数据行。•②只有两个或很少几个值的列(如性别,只有两个值“男”或“女”),以这样的列创建索引并不能得到建立索引的好处。•③以bit、text、image数据类
型定义的列。•④数据行数很少的小表一般也没有必要创建索引。83.2聚簇索引与非聚簇索引3.2.1索引的分类根据索引的顺序与数据表的物理顺序是否相同,可以把索引分成两种类型:聚簇索引与非聚簇索引。和表及视
图一样,索引也是数据库对象。聚簇索引(ClusteredIndex)数据表的物理顺序和索引表的顺序相同,它根据表中的一列或多列值的组合排列记录。非聚簇索引(NonclusteredIndex)数据表的物理顺序和索引表的顺序不相同,索引表仅仅包含指向数据表的指针,这些指
针本身是有序的,用于在表中快速定位数据。9SQLServer2005中,创建索引有两种方法:•使用T-SQL语句创建索引•使用SQLServerManagementStudio创建索引在一个表的一个或多个列上创建索引时,应考虑以下几点:•①当在一个表上创建PRIMARYKE
Y约束或UNIQUE约束时,SQLServer自动创建唯一性索引。不能在已经创建PRIMARYKEY约束或UNIQUE约束的列上创建索引。定义PRIMARYKEY约束或UNIQUE约束与创建标准索引相比应是首选的方法。•②必须是表的拥有者才能创
建索引。•③在一个列上创建索引之前,确定该列是否已经存在索引。•④也可以在视图上创建索引,但创建视图时必须带参数SCHEMABINDING。在视图上创建索引的创建方法参见SQLServer2005随机帮助。3.3索引
的创建与管理103.3.1使用T-SQL语句创建索引3.3.2使用T-SQL语句管理索引3.3.3使用SQLServerManagementStudio管理索引3.3索引的创建与管理111.创建索引的SQL语句语法创建索引使用的是CREATEINDEX语句
。CREATEINDEX语句的语法形式如下:CREATE[UNIQUE][CLUSTERED|NONCLUSTERED]INDEXindex_nameONtable_name(column_name[ASC|DESC][,...n])[WITH[PAD_INDEX][[,]FILLFACT
OR=fillfactor][[,]DROP_EXISTING]]3.3.1使用T-SQL语句创建索引12在以上语法形式中:•UNIQUE:指定创建的索引是唯一索引。如果不使用这个关键字,创建的索引就不是唯一索引。•CLUSTERED|NONCLUSTERED:指定被创建
索引的类型。使用CLUSTERED创建的是聚簇索引;使用NONCLUSTERED创建的是非聚簇索引。这两个关键字中只能选其中的一个。•index_name:为新创建的索引指定的名字。•table_name:创建索引的基表的名字。•column_na
me:索引中包含的列的名字。•ASC|DESC:确定某个具体的索引列是升序还是降序排序。默认设置为ASC升序。•PAD_INDEX和FILLFACTOR:填充因子,它指定SQLServer创建索引的过程中,各索引页的填满程度。
•DROP_EXISTING:删除先前存在的、与创建索引同名的聚簇索引或非聚簇索引。132.创建唯一索引索引按照结构可分为聚簇索引和非聚簇索引两种不同的类型。按照实现的功能分,有一类索引被称作“唯一索引”。它既可以采用聚簇索引的结构,又可以采用非聚簇索引的结
构。唯一索引的特征:•①不允许两行具有相同的索引值。•②可用于实施实体完整性。•③在创建主键约束和唯一约束时自动创建唯一索引。在已有数据的表上创建唯一索引时,如果在该列数据存在重复值,那么系统将返回错误信息。在实际的编程应用中会经常使用到唯一
索引。因为在一个表中,可能会有很多列的列值需要保证其唯一性,如:有身份证号、工号、学号等,可在这些列上创建唯一索引。14【例3-1】在JWGL数据库的BOOK表上创建一个名为book_id_index的唯一性聚簇索引,索引关键字为book_id,升序,填充因子50%USEjwglGOCREAT
EUNIQUECLUSTEREDINDEXbook_id_indexONbook(book_idASC)WITHFILLFACTOR=50153.创建复合索引有些索引列只有一列,而有些索引列由两列或更多列组成。我们把由两列或更多列组成的索引称作“复合索引”。⑴复合
索引的特征•①把两列或更多列指定为索引列。•②将复合列作为一个整体进行搜索。•③创建复合索引中的列序不一定与表定义列序相同。【例-2】在JWGL数据库的student_course表上创建一个名为student_course_index的非聚簇复合索引,索引关键字
为student_id,course_id,升序,填充因子50%USEjwglGOCREATENONCLUSTEREDINDEXstudent_course_indexONstudent_course(student
_idASC,course_idASC)WITHFILLFACTOR=5016⑵创建复合索引应注意的几点•①查询的WHERE子句必须引用复合索引中的第一列,以便让查询优化程序使用该复合索引。•②被查询表中需要频繁访问的
列应考虑建复合索引以提高查询性能。•③在一个复合索引中索引列最多可组合16列。•④列的顺序很重要,应首先定义最具唯一性的列,(column1,column2)上的索引不同于(column2,column1)上的索引。•⑤使用复合索引能增加查询性能,并减少表上创建索引的数量。171.
使用T-SQL语句查看索引在创建索引之前或在创建索引之后,可以用sp_helpindex或sp_help系统存储过程查看表的索引。【例3-3】用系统存储过程sp_helpindex查看JWGL数据库中表book的索引信息。USEjwglGOEXECsp_helpindexbook3
.3.2使用T-SQL语句管理索引182.使用T-SQL语句对索引更名在创建索引之后,可以用sp_rename系统存储过程重新命名表的索引。【例3-4】用系统存储过程sp_rename将表book的索引book_id_index重新命名为book_id_index1。USEjwglGOsp_
rename‘book.book_id_index‘,‘book_id_index1'注意:要重命名的索引要以“表名.索引名”的形式给出。但新索引名不能给出表名。193.使用T-SQL语句删除索引在创建索引之后,如果该索引不再需要,可以用DROP语句将其删除。DR
OP语句的语法如下:DROPINDEXtable.index[,...n]【例3-5】用DROP语句将表book的索引“book_id_index1”删除。USEjwglGODROPINDEXbook.boo
k_id_index1注意:•①被删除的索引要以“表名.索引名”的形式给出。•②删除索引时要注意,如果索引是在CREATETABLE语句中创建的,只能用ALTERTABLE语句删除索引。如果索引是用CREATEIN
DEX创建的,可用DROPINDEX删除。20使用SQLServerManagementStudio可以创建索引。3.3.3使用SQLServerManagementStudio管理索引21在SQLServerManagementStudio的“对象
资源管理器”面板中,使用与创建索引同样的方法即可看到该索引对应的信息。使用系统存储过程sp_helpindex查看指定表的索引信息。【例6.5】使用系统存储过程sp_helpindex查看book数
据库中book1表的索引信息。在SQLServerManagementStudio查询窗口中运行如下命令:USEbookGOEXECsp_helpindexbook1GO显示索引信息22使用SQLServerManagem
entStudio删除索引。3.3.3使用SQLServerManagementStudio管理索引233.2视图视图是一种数据库对象,是从一个或者多个数据表或视图中导出的虚表,视图的结构和数据是对数据表进行查询的结果。视图被定义后便存储在数据库中,通过
视图看到的数据只是存放在基表中的数据。当对通过视图看到的数据进行修改时,相应的基表的数据也会发生变化,同时,若基表的数据发生变化,这种变化也会自动地反映到视图中。视图可以是一个数据表的一部分,也可以是多个基表的联合;视图也可以由一个或多个其他视图产生。一旦视图定义后,就
可以用select语句象对真实表一样查询。243.2.1创建视图使用Transact-SQL语句创建视图1.创建视图的SQL语句的语法形式CREATEVIEW[<owner>.]view_name[(column_
name[,...n])][WITHENCRYPTION]ASselect_statementFROMtable_nameWHEREsearch_condition[WITHCHECKOPTION]其中:•·view_name:为新创建的视图指定的名字
,视图名称必须符合标识符规则。•·column_name:在视图中包含的列名,也可以在SELECT语句中指定列名。25•·table_name:视图基表的名字。•·select_statement:选择哪些列进入视图的SELECT语句。•·WHEREsearch_condition:
基表数据进入视图所应满足的条件•·WITHCHECKOPTION:迫使通过视图执行的所有数据修改语句必须符合视图定义中设置的条件。•·WITHENCRYPTION:对视图的定义进行加密。2.用SQL语句创建视图的步骤在创建视图时,应首先测试SELECT语句以确保能返回正确的结果。创建视
图的步骤如下:•①编写用于创建视图的SELECT语句。•②对SELECT语句进行测试。•③检查测试结果是否正确,是否和预期的一样。•④创建视图。263.在创建视图的时候,应该考虑以下因素•①在CREATEVIEW语句中,不能包括ORD
ERBY、GROUPBY子句,也不能出现INTO关键字。•②创建视图所参考基表的列数最多为1024列。•③创建视图不能参考临时表。•④在一个批处理语句中,CREATEVIEW语句不能和其他Transact-SQL语句混合使用。•⑤尽量避免使用
外连接创建视图。27使用SQLServerManagementStudio创建视图假设要从student表中建立一个性别为“男”、包含student_id、student_name、class_id、sex四列信息的视图。使用SQLServerManagement
Studio创建视图的具体步骤如下:1)首先进入SQLServerManagementStudio。2)按顺序展开“数据库”、要创建视图所属的数据库、再展开“视图”子节点。3)右边“摘要”窗口显示的是数据库中已经存在的视图,右击窗口的空白处,在弹出的快捷菜单上选择
“新建视图”项,系统弹出如图9-1的“添加表”窗口,这个窗口用于为新创建的视图提供基础数据。该窗口有三个选项卡,表、视图及函数,这意味着可以以表、视图及表值函数为基础数据创建新的视图。284)点击“添加”,选择表student,再点击“关闭”。系统呈现如图9-2的视图建立窗口。图9-1创建
视图的窗口29图9-2视图建立窗口30在SQL查询条件窗格中输入查询条件语句:SELECTstudent_id,student_name,class_id,sexFROMstudentWHEREse
x=15)确认结果正确后,点击工具栏上的“”按钮,保存当前创建的视图,输入视图的名称,点击“确定”按钮,一个视图也就创建完成了。313.2.2使用视图的优点和缺点1.视图的优点•视图可以屏蔽数据的复杂性,简化用户对数据库的操作,
还可以使用视图重新组织数据。•视图可以让不同的用户以不同的方式看到不同或者相同的数据集。•安全保护:视图可以定制不同用户对数据的访问权限。2.视图的缺点•性能降低:•修改的限制:323.2.3创建水平视图视图的常见用法是限制用户只能够存取表中的某些数据行,用这种方法产生的视图称为
水平视图,即表中行的子集。【例9-1】在数据库JWGL的表student上创建一个视图student_view1,视图的数据包括班级号为‘g99402‟或‘g99403‟所有学生的资料。USEjwglGOCREATEVIEWstudent
_view1ASSELECT*FROMstudentWHERE(class_id=‟g99402‟ORclass_id=‟g99403‟)333.2.4创建投影视图如果限制用户只能存取表中的部分列的数据,那么,使用这种方法
创建的视图就称为投影视图,即表中列的子集。【例9-2】创建一个名为“studdent_view2”的视图,它从数据库JWGL的student表中查询出性别为“男”的所有学生的姓名、性别、家庭住址资料。USEjwglGOCREATE
VIEWstudent_view2ASSELECTstudent_idAS学号,student_nameAS姓名,sexAS性别,class_idAS班级,home_addrAS家庭住址,entrance_dateAS入学时间,birthAS出生年月FROMstudentWHEREsex=1WIT
HCHECKOPTION343.2.5创建联合视图使用视图的一个原因是简化多表查询,可以生成从多个表中提取数据的联合视图(joinedView)把查询结果表示为一个单独的“可见表”。【例9-3】创建一个名为“student_view3”的视图,它是由表course、book及clas
s_course创建的一个显示“g99402”班所开课程的课程名、所用教材的教材名、出版社及作者的视图。USEjwglGOCREATEVIEWstudent_view3WITHENCRYPTION/*
加密视图*/ASSELECTcourse.course_nameAS课程名,book.book_nameAS书名,book.publish_companyAS出版社,book.authorAS作者FROMcou
rse,book,class_courseWHERE(course.book_id=book.book_idANDclass_course.course_id=course.course_id)AND(class_course.class_id='g99402')353.2.6创建包含集合函数的
视图在视图定义中可以包含GROUPBY和集合函数,从而将这些汇总数据放到一个“可见”的表中,允许用户对它们做进一步的查询。要注意,出现在SELECT子句中的列名,要么包含在集合函数中,要么包含在GROU
PBY子句中。【例9-4】使用集合函数SUM和GROUPBY子句以student_course表为基表,创建一个名为“student_sum_view4”、能显示所有学生学号和总成绩的视图。USEjw
glGOCREATEVIEWstudent_sum_view4(学号,总成绩)ASSELECTstudent_id,sum(grade)FROMstudent_courseGROUPBYstudent
_id注意:与水平视图和投影视图不同,本例产生的视图中的行与基本表中的行不是一一对应的,它是一些行数据的汇总,因此,不能通过视图来修改数据。363.2.7创建视图的视图前面创建的视图都是在表的基础上创建的,在视图的基
础上还可以创建视图。【例9-5】从视图student_view1创建一个名为“student_view5”,能查询出班级名为“g99402”的所有学生资料的视图。USEjwglGOCREATEVIEWstudent_vi
ew5ASSELECT*FROMstudent_view1WHEREclass_id='g99402'GO373.2.8查看视图信息使用系统存储过程查看视图信息•sp_help数据库对象名称•sp_helptext视图(触发器、存储过程)•sp_depends数据库对象名称1.使用系统存储
过程•①查看视图的名称、拥有者及创建日期等信息sp_helpstudent_view1•②查看视图的定义脚本sp_helptextstudent_view1•③查看数据的来源sp_dependsstudent_view12.使用SQLServerMa
nagementStudio查看视图383.2.9视图的修改1.使用SQLServerManagementStudio修改视图(略)2.使用Transact-SQL语句修改视图ALTERVIEWview_name[(colu
mn[,...n])][WITHENCRYPTION]ASselect_statement[WITHCHECKOPTION]在以上语句的语法中:•·view_name:被修改的视图的名字。•·column_name:在视图中包含的列名。•·WITHCHECKOPTION:迫使通过视图进行数据修
改的所有语句必须符合视图定义中设置的条件。39•·table_name:视图基表的名字。•·WITHENCRYPTION:对包含创建视图的SQL脚本进行加密。【例9-6】修改视图student_view1的定义,使其从stu
dent表中查询出性别为“女”的所有学生的资料。USEjwglGOALTERVIEWstudent_view1ASSELECT*FROMstudentWHEREsex=0403.2.10视图的删除删除一个视图
,就是删除视图的定义及其赋予的全部权限,而原先通过视图获得的数据并没有被删除。删除视图参考表的时候,视图不会被删除,视图必须被单独删除。删除视图有两种方法,一是使用SQLServerManagementStu
dio删除,二是用DROPVIEW语句删除。1.用DROPVIEW语句删除视图DROPVIEW语句的语法形式如下:DROPVIEWview_namel,view_name2,…使用DROPVIEW语句可以一次删除多个视图。下面的例子是将student_view5
视图删除。DROPVIEWstudent_view5412.使用SQLServerManagementStudio删除视图•①进入SQLServerManagementStudio,展开相应的服务器组和相应的服务器节点。•②展开“数据库
”节点,然后展开视图所属的数据库,再展开“视图”子节点。•③在右侧的视图资料显示窗口上,右击视图student_view1,在弹出的快捷菜单中,单击“删除”菜单命令,再单击“全部除去”按钮即可将选定的视图删除。423.2.12视图数据查询、插入、修
改与删除用T-SQL语句进行视图数据的查询、插入、修改与删除使用T-SQL语句可以进行视图数据的查询、插入、修改与删除。其语法形式和对表中数据的查询、插入、修改与删除操作几乎一样。1.从视图中查询数据【例9-7】从视图stud
ent_view2中查询出学生姓名为“钱利”的学生资料。USEjwglGOSELECT*FROMstudent_view2WHERE姓名='钱利'想一想,为什么WHERE子句不能用student_name='
钱利'?432.向视图插入数据【例9-8】向视图student_view2中插入一行数据。学号、姓名、性别、班级、家庭住址\入学时间,出生年月分别是“g9940210”,“赵青”,“男”,“g99402”,“南京中山北路10号”,‘1999-09-01‟,„1985-01-09‟。USEjwg
lGOINSERTINTOstudent_view2(学号,姓名,性别,班级,家庭住址,入学时间,出生年月)VALUES('g9940210','赵青',1,'g99402','南京中山北路10号','
1999-09-01','1985-01-09')443.修改视图中的数据【例9-9】将视图student_view2中“钱利”同学的家庭住址改为“扬州市南京路8号”USEjwglGOUPDATEstudent_v
iew2SET家庭住址='扬州市南京路8号'WHERE姓名=„钱利‘4.删除视图中的数据【例9-10】将视图student_view2中“钱利”同学的资料删除USEjwglGODELETEFROMstudent_view2W
HERE姓名='钱利'45用SQLServerManagementStudio进行视图数据的插入、修改与删除使用SQLServerManagementStudio对视图插入、修改与删除数据•①进入
SQLServerManagementStudio,展开相应的服务器组和相应的服务器节点。•②展开“数据库”节点,然后展开视图所属的数据库,再展开“视图”子节点。•③右击要操作的视图名称,分别单击“打开视图”、“返回所有行”,便会出现图9-3的视
图数据显示窗口。•插入数据:直接在视图的最后一行进行数据的插入。•修改数据:直接点击要修改的数据进行修改。•删除数据:右击图9-3的窗口的要删除数据行的最左列,在弹出的快捷菜单上点击“删除”•④操作完成后,点击工具栏上的“!”,确认视图数据的修改。463.3存储过程存储过程
是一系列预先编辑好的、能实现特定数据操作功能的SQL代码集,它与特定的数据库相关联,存储在SQLServer服务器上。用户可以像使用函数一样重复调用这些存储过程,实现它所定义的操作。存储过程分为三类:系统提供的存储过程、
用户定义的存储过程和扩展存储过程。•系统存储过程系统存储过程是指安装SQLServer时由系统创建的存储过程。存储在master数据库中,其前缀为sp_。系统存储过程主要用于从系统表中获取信息,也为系统管理员和有权限的用户提供更新系统表的途径。它们中的大部分可以在用户数据库中使用。•扩展存储
过程扩展存储过程是对动态链接库(DLL)函数的调用。其前缀为xp_。它允许用户使用DLL访问SQLServer,用户可以使用编程语言(诸如C或C++等)创建自己的扩展过程。•用户定义的存储过程由用户为完成
某一特定功能而编写的存储过程。47存储过程的优点存储过程是一种把重复的任务操作封装起来的一种方法,支持用户提供参数,可以返回、修改值,允许多个用户使用相同的代码,完成相同的数据操作。它提供了一种集中且一致的实现数据完整性逻辑的方法。存储过程用于实现频繁使用的查询、业务规则、
被其它过程使用的公共例行程序。存储过程具有以下优点:•存储过程提供了处理复杂任务的能力存储过程提供了许多标准SQL语言所没有的高级特性,它通过传递参数和执行逻辑表达式,能够使用十分复杂的SQL语句处理复杂任务。•增强
代码的重用性和共享性每一个存储过程都是为了实现一个特定的功能而编写的模块,模块可以在系统中重复地调用,也可以被多个有访问权限的用户访问。所以,存储过程可以增强代码的重用性和共享性,加快应用系统的开发速度,减少工作量,提高开发的质量和效率。48•减少网络数据流量存储过程是与数
据库一起存放在服务器中并在服务器上运行的。应用系统调用存储过程时只有触发执行存储过程的命令和执行结束返回的结果在网络中传输。用户端不需要将数据库中的数据通过网络传输到本地进行计算,再将计算结果通过网络传送到服务器。所以,使用存储过程可以减少网络中数据流量。•加快
系统运行速度第一次执行后的存储过程会在缓冲区中创建查询树,第二次执行时就不用进行预编译,从而加快了系统运行速度。另外,由于存储过程是在服务器上运行,分担了用户端的数据处理工作,也加快了应用系统的处理速度。•加强系统安全性SQLServer可以不授予用户某些表、视图的访问权限,但授予用户执行存储过
程的权限,通过存储过程来对这些表或视图进行访问操作。这样,既可以保证用户能够通过存储过程操作数据库中的数据,又可以保证用户不能直接访问与存储过程相关的表,从而保证表中数据的安全性。493.3.1使用T-SQL语句创建存储过程1.创建存储过程的SQL语句语法创建一个存
储过程的语法如下:CREATEPROC[EDURE][OWNER.]procedure_name[({@parameterdata_type}[VARYING][=default][OUTPUT])][,...n][WITH{RECOMP
ILE|ENCRYPTION|RECOMPILE,ENCRYPTION}]ASsql_statement[...n]只有两个必需的参数必须传递给CREATEPROCEDURE语句:创建存储过程所需的procedure_name和sql_statem
ents。50在以上语句的语法中:●procedure_name:为新创建的存储过程所指定的名字,它必须遵循标准SQLServer命名约定,且必须在同一个数据库中是唯一的。●@parameter:存储过程的输入或输出参数。●default:参数缺省值。
●WITHRECOMPILE:重编译选项。●sql_statements:存储过程中实现功能的SQL语句。2.创建步骤一般来说,创建一个存储过程应按照以下步骤进行:•①编写SQL语句。•②测试SQL语句是否正确,并能实现功能要求。•③若得到的结果数据
符合预期要求,则按照存储过程的语法,创建该建存储过程。•④执行该存储过程,验证其正确性。513.存储过程创建示例【例11-1】使用Transact-SQL语句在books数据库中创建一个名为p_books的存储过程。该存储过程返回boo
ks表中所有的图书记录。createprocp_booksasselect*frombooks执行以上脚本,便可创建存储过程p_books。如要执行该存储过程,可在查询分析器中执行如下语句:EXECp_books524.创建存储过程的注意事项在创建存储过程的时候,需要注意如下几点
:•①每个存储过程应该完成一项单独的工作。•②为防止别的用户看到自己所编写的存储过程的脚本,创建存储过程时可以使用参数WITHENCRYPTION。•③一般存储过程都是在服务器上创建和测试,在客户机上使
用时,还应该进行测试。533.3.2创建带输入参数的存储过程输入参数是指由调用程序向存储过程传递的参数。它们在创建存储过程语句中被定义,其参数值在执行该存储过程时由调用该存储过程的语句给出。具体语法如下:@parameter_namedataype[=default]其中:●@pa
rameter_name:存储过程的输入参数名,必须以@符号为前缀。执行该存储过程时,应该向输入参数提供相应的值。●datatype:该参数的数据类型说明,它可以是系统提供的数据类型,也可以是用户定义的数据类型。●default:如果执行存储过程时未提供该参数值,则使用DEF
AULT值。54【例11-2】继续上一节的例子。建立一个存储过程,选择某一个指定出版社的名称。•createprocp_books_publisher@publishervarchar(50)•asselect*frombooks•wherepublisher=@publisher55用户可以
运行下面的语句来执行它,以查询清华大学出版社出版的所有图书:execp_books_publisher'清华大学出版社‘这种类型的存储过程存在的一个问题,如果用户不给出传递给该存储过程所需参数中的任何一个,将会产生错误。解决这种问题的一种方法是建立使用默
认值的参数。要做到这一点,用户必须在参数的定义之后加上等号,并在等号后面写出默认值。如将上例中第二行:@publishervarchar(50)替换为:@publishervarchar(50)='%',重新创建存储过程p_books
_publisher,如果执行该存储过程时不提供任何参数,则执行返回的结果集将是空集,而不会产生错误。56【例11-3】为bookShop数据库建立一个存储过程,通过执行存储过程将用户信息添加到Users表。•CREATEPROCEDUREspAddUser•@Use
ridvarchar(50)=NULL,•@Pwdvarchar(50)=NULL,•@Usernamevarchar(50)=NULL,•@sexchar(2)=NULL,•@addressvarchar(500)=NULL,•@emailvarchar(50)=NU
LL,•@telphonevarchar(50)=NULL,•@mobilevarchar(50)=NULL•AS•IF@UseridISNULLOR@PwdISNULLOR@UsernameISNULLOR@s
exISNULL57•BEGIN•PRINT'请重新输入该用户信息!'•PRINT'你必须提供用户的用户名、用户密码、用户姓名及性别。'•PRINT'(用户地址、邮箱、固定电话和移动手机可以为空)'•RETURN•
END•else•INSERTUsers(userid,pwd,username,Sex,address,email,telphone,mobile)•VALUES•(@userid,@pwd,@username,@Sex,@address,@email,@telphone,@mobile)•
PRINT'用户'+@userid+'的信息成功添加到表Users中。'583.3.3创建带输出参数的存储过程具体语法如下:@parameter_namedataype[=default]OUTPUT其中:●@parameter_name:存储过程的输出参数名,必须以@符号为前缀。●d
atatype:输出参数的数据类型说明,它可以是系统提供的数据类型,也可以是用户定义的数据类型。●OUTPUT:指明该参数是一个输出参数。这是一个保留字,输出参数必须位于所有输入参数之后。返回值是当存储过程执行完成时参数的当
前值。为了保存这个返回值,在调用该过程时SQL调用脚本必须使用OUTPUT关键字。59【例11-4】创建一个实现加法计算并将运算结果作为输出参数的存储过程。CREATEPROCEDUREspAdd@Value1INT,@Value2INT,@Res
ultValueINTOUTPUTASSELECT@ResultValue=@Value1+@Value2GO创建了上面的存储过程之后,下面我们来看看怎样使用它。为了使用spAdd,接受其输出参数的返回值,调用它的程序中也必须定义一个变量,并使用OUTPUT关键字指定它为调
用输出参数。60【例11-5】执行spAdd存储过程,输入参数由value1和value2提供,输出参数valueTotal。DECLARE@value1INTDECLARE@value2INTDECLARE@valueTotalINTSET@value1=125SET@value2=3SET@v
alueTotal=34EXECspAdd@value1,@value2,@valueTotalOUTPUTPRINTCONVERT(CHAR(5),@value1)+„与’+CONVERT(CHAR(5),@value2)+
„的和等于:‟+CONVERT(CHAR(5),@valueTotal)GO61结果消息显示:125与3的和等于:128在上述例子中,若调用中省略OUTPUT,调用仍能执行,但@valueTotal值仍为34。若在存储过程的定义中省略OUTPUT,调用时会出错。实际上,每个存储过程的执行
,都将自动返回一个返回状态(可以通过@return_status获得),用于告诉调用程序“执行该存储过程的状况”。调用程序可根据返回状态作相应的处理。一般而言,系统使用0表示该存储过程执行成功。用户也可以在存
储过程中使用RETURN来返回指定的值。623.3.4查看、修改和删除存储过程查看存储过程存储过程被创建以后,它的名字存放在当前数据库的系统表sysobjects中,创建它的源代码存放在syscomm
ents系统表中。可以通过SQLServer2000提供的几个系统存储过程来查看用户存储过程的有关信息。1.用T-SQL语句查看存储过程⑴查看存储过程的定义系统存储过程sp_helptext可查看未加密的存储过
程的定义脚本,也可用于查看规则、默认值、用户定义函数、触发器或视图的定义脚本。使用其语法如下:sp_helptext[@objname=]‟name‟其中:[@objname=]‟name‟是对象的名称,要查看的对象必须在当前数据库中。这里为存储过
程名。例如,执行sp_helptextspAdd,可显示存储过程spAdd的定义脚本。63⑵查看有关存储过程的信息使用系统存储过程sp_help可查看有关存储过程的信息。具体语法形式如下:sp_helpproc_name其中:●proc_name
:要查看的存储过程名。执行上面的语句后,系统将返回指定存储过程的名称、拥有者、类型和创建时间,并且返回这个存储过程所有参数的名称、类型、宽度、精度和默认值等信息。2.使用SQLServerManage
mentStudio查看存储过程•1)展开服务器。•2)分别展开“数据库”、“JWGL”、“可编程性”、“存储过程”。•3)右击需要查看的存储过程,然后单击“属性”命令,系统将弹出如下图的“存储过程属性”窗口。•4)点击“常规”,可以查看到该存储过程属于哪个数据库,创建日期,属于哪个数据库用
户等信息。•5)点击“权限”,可以为该存储过程添加用户并授予其权限。64修改存储过程1.使用T-SQL语句修改存储过程Transact-SQL中提供了ALTERPROCEDURE语句来更改已经创建的存储过程
,它不会更改权限,也不影响相关的存储过程或触发器。它的语法如下所示:ALTERPROC[EDURE]procedure_name[{@parameterdata_type}[VARYING][=default][OUTPUT]][,...n][WITH{RECOMPILE|ENCRYPTION
|RECOMPILE,ENCRYPTION}][FORREPLICATION]ASsql_statement[...n]652.使用SQLServerManagementStudio修改存储过程在SQLServerManagementStudio中修改存储
过程的步骤如下:•1)展开服务器。•2)分别展开“数据库”、“JWGL”、“可编程性”、“存储过程”。•3)右击需要修改的存储过程,然后单击“修改”命令。•4)进行存储过程的修改。66删除存储过程对于不再需要的存储过程,可将其删除。可以使用SQL语句,也可以使用SQLServerMa
nagementStudio。1.使用SQL语句删除存储过程从当前数据库中删除一个或多个存储过程的T-SQL语句是DROPPROCEDURE。具体语法如下:DROPPROCEDURE{procedure}[,…n]其中参数:•●procedure:是要删除的存储过程的
名称。•●n:表示可以指定多个存储过程。例如,要将spAdd存储过程删除,则可以执行DROPPROCspAdd语句。672.使用SQLServerManagementStudio删除存储过程使用SQLServerManagementStud
io中删除存储过程的步骤如下:1)展开服务器。2)分别展开“数据库”、“JWGL”、“可编程性”、“存储过程”。3)右击需要删除的存储过程,然后单击“删除”命令。4)在系统弹出的“删除对象”对话
框中点击“确定”即可删除该存储过程。683.4触发器触发器的概念及分类触发器是一种特殊类型的存储过程,它不同于前面介绍过的一般的存储过程。一般的存储过程通过存储过程名称被直接调用,而触发器主要是通过事
件进行触发而被执行触发器是一个功能强大的工具,它与表格紧密相连,在表中数据发生变化时自动强制执行。触发器可以用于SQLServer约束、默认值和规则的完整性检查,还可以完成难以用普通约束实现的复杂功能。69触发器(Trigger)是一种实施复杂数据完整性的特殊存
储过程.在对表或视图执行UPDATE、INSERT或DELETE语句时自动触发执行,以防止对数据进行不正确、未授权或不一致的修改。触发器是与表紧密联系在一起的,是在特定表上进行定义的,这个特定表也被称为触发器表。触发器和一般的存储过程又有
一些不同,它不可以像调用存储过程一样由用户直接调用执行。触发器与表是密不可分的,触发器是不能离开表而独立存在的,触发器主要用于保护表中的数据,实现数据的完整性。对表中数据的操作有三种基本类型,数据插入、修改、删除,因此
,触发器也有三种类型:INSERT、UPDATE、DELETE。当向触发器表中插入数据时,如果该触发器表有INSERT类型的触发器,INSERT触发器就被触发执行。同样的道理,UPDATE触发器会被数据更新触发执行、DELETE触发器会被
数据删除触发执行。70触发器的工作原理SQLServer为执行的触发器创建一个或两个专用的临时表:inserted表或者deleted表。inserted表和deleted表的结构总是与被该触发器作用的表的结构相同,而且只能由创建它们的触发器引用。它们是临时的逻辑表,由系统来维
护,不允许用户直接对它们进行修改。它们存放于内存中,并不存放在数据库中。触发器工作完成后,与该触发器相关的这两个表也会被删除。1.INSERT触发器的工作原理当一个记录插入到表中时,INSERT触发器自动触发执行,相应的插入触发器创建一个inserted表,新的记
录被增加到该触发器表和inserted表中。它允许用户参考初始的INSERT语句中的数据,触发器可以检查inserted表,以确定该触发器里的操作是否应该执行和如何执行。712.DELETE触发器的工作原理当从表中删除一条记录时,DELETE
触发器自动触发执行,相应的删除触发器创建一个deleted表,deleted表是个逻辑表,用于保存已经从表中删除的记录,该deleted表允许用户参考原来的DELETE语句删除的已经记录在日志中的数据
。应该注意:当被删除的记录放在deleted表中的时候,该记录就不会存在于数据库的表中了。因此,deleted表和数据库表之间没有共同的记录。3.UPDATE触发器的工作原理修改一条记录就等于插入一条新记录,删
除一条旧记录。进行数据更新也可以看成由删除一条旧记录的DELETE语句和插入一条新记录的INSERT语句组成。当在某一个触发器表的上面修改一条记录时,UPDATE触发器自动触发执行,相应的更新触发器创建一个deleted表和inserted表,表中原来的记录移动到del
eted表中,修改过的记录插入到了inserted表中。723.4.1触发器的创建使用T-SQL语句创建触发器1.创建触发器的SQL语句语法:创建触发器的一般语法如下。CREATETRIGGERtrigger_nameONtable_name[WITHENCRYPTION]FO
R{[DELETE][,][INSERT][,][UPDATE]}ASsql_statement●trigger_name:要创建的触发器名称。触发器名称必须符合标识符规则,并且在数据库中必须唯一。●table_name:指定所创建的触发器与之相关联的表名。
必须是一个现存的表。73●WITHENCRYPTION:加密创建触发器的文本。●FOR{[INSERT][,][DELETE][,][UPDATE]}:指定所创建的触发器将在发生哪些事件时被触发,也即指定创建触发器的类型。“INSERT”,表示创建插入触发器;“DELETE”,表示创建删除触
发器;“UPDATE”表示创建更新触发器。必须至少指定一个选项。在触发器定义中允许使用以任意顺序组合的这些关键字。如果指定的选项多于一个,以逗号分隔这些选项。sql_statement:指定触发器执行的SQL语句。触发器只能在当前数据库中创建,并且一个触发
器只能作用在一个表上。在同一条CREATETRIGGER语句中,可以为多种用户操作(如INSERT和UPDATE)定义相同的触发器操作。值得注意的是,在SQLServer中也可以对视图建立触发器,只要将视图名称作为table_name用在创建语法中就可以了。但是
,对视图建立触发器有一些限制,详细信息请参考SQLServer联机丛书。742.创建INSERT触发器下面以为表Basket建立一个插入触发器为例,介绍创建INSERT触发器的方法。当增加一条订购记录,即向
表Basket中插入一行数据时,需要更改所订购图书的记录,以增加该图书的销售数量。下例使用INSERT触发器自动完成这个工作。【例12-1】为Basket表建立INSERT触发器以自动更新Books表销售数量。75USEBookShopGOCREATET
RIGGERBasket_insertONBasketFORINSERTASDECLARE@OrderCountTINYINTSELECT@OrderCount=OrderCountFROMinsertedBEGINUPDATEBooksSETBuyCount=Bu
yCount+@OrderCountFROMBooks,insertedWHEREBooks.Id=inserted.bookIdEND76Books表BuyCount列自动更新的原因是:在Basket表上
执行了INSERT操作后,触发了插入触发器Basket_insert,该触发器自动对图书销售数量进行累加(或重新统计)。从上述例子可以看出,通过触发器可以维护数据完整性。在上述定义插入触发器时,使用了inserted专用临时表,它保存所插入行的一个拷贝。773.创建DELETE
触发器当删除一条用户订购记录,即从表Basket中删除一行数据时,需要更改所订购图书的销售数量。对Basket_insert的代码稍加修改就可以得到能自动完成这个工作的删除触发器。【例12-2】为Basket表建立DELETE触发器,在删除订购记录时自动更新Books表中相应图书的销
售数量。78USEBookShopGOCREATETRIGGERBasket_deleteONBasketFORDELETEASDECLARE@OrderCountTINYINTDECLARE@BuyCountTINYINTSELECT@OrderCount=OrderCou
ntFROMdeletedSELECT@BuyCount=BuyCountFROMbooksIF(@BuyCount>@OrderCount)BEGINUPDATEBooksSETBuyCount=Bu
yCount-@OrderCountFROMBooks,deletedWHEREBooks.Id=deleted.bookIdENDELSEBEGINPRINT'执行错误,删除操作被取消!'INSERTINTOBasketSELECT*FROMdeletedEND79
在Books表中BuyCount列的值自动修改的原因是:在Basket表上执行删除订购记录的操作时,触发了Basket表上的删除触发器,该触发器将Books表上的BuyCount字段值减在Basket表上删除订购记录的OrderCount值。在上述定义触发器时
,使用了deleted逻辑表。deleted表是一个逻辑表,在执行删除触发器语句时,表中被删除的行存放在deleted表中。804.创建UPDATE触发器【例12-3】为Books表建立UPDATE触发器,在图书的销售价格变更时自动更新Basket表中相应图书的
销售价格。USEBookShopGOCREATETRIGGERBooks_updateONBooksFORUPDATEASDECLARE@SalePricefloatSELECT@SalePric
e=SalePriceFROMinsertedUPDATEBasketSETSalePrice=@SalePriceFROMBasket,deletedWHEREBasket.BookId=deleted.IdGO81在对Books表进行UPDATE操作时,触发了更新触发器
Books_update,该触发器将Books表和Basket表中相关图书的销售单价都重新进行了更新。由于Books表在进行UPDATE操作时,把更新前后的数据值分别拷贝到了deleted和inserte
d临时表中。所以可以从这两个表中得到图书修改前后两个相关的销售价格SalePrice,从而对Basket表中的图书销售价格进行重新更新。82使用SQLServerManagementStudio创建触发器在SQLServerM
anagementStudio中使用以下步骤创建触发器:•1)打开SQLServerManagementStudio。•2)分别展开“数据库”、“JWGL”、“表”。•3)点击将在其上创建触发器的表(如student),再右击“触发器”,在系统弹出的快捷菜单上单击“新建触发器”,系统文档窗口触发
器创建模板。•4)在触发器创建模板上输入触发器创建文本。•5)点击工具栏上的执行按钮,完成触发器的创建,如需保存触发器创建文本,点击工具栏上的保存按钮。833.4.2查看、修改和删除触发器查看触发器信息使用T-SQL语句或SQLServerManagementStudio
可以获取表中触发器的类型、触发器名称、触发器所有者,以及触发器创建的日期。如果触发器创建或修改时没有进行加密,还可以获取触发器定义的有关信息,了解它如何影响所在的表。由于触发器也是一种特殊的存储过程,所以触发器被创建以后,它
的名字存放在系统表sysobjects中,它的创建源代码存放在syscomments系统表中。1.使用T-SQL语句查看触发器信息⑴查看表中的触发器信息使用系统存储过程sp_helptrigger可以查看指定表中所定义的触发器及它们的类型。例如,要查看s
tudent表中触发器信息,可使用下列语句:EXECsp_helptriggerstudent84⑵查看触发器定义使用系统存储过程sp_helptext可以查看指定触发器的定义文本。例如,要查看student_insert触发器的定
义代码,就可以使用下列语句:EXECsp_helptext„student_insert‟在查询分析器中可以看到如图12-4所示执行界面和结果。图12-4使用系统存储过程查看触发器定义⑶查看触发器的相关性使用系统存储过程sp_depend
s可以查看指定触发器的相关性,了解触发器所依赖的表或视图。例如,可以使用下面的语句来查看student_delete触发器的相关性:EXECsp_depends„student_delete‟852.使用SQLSer
verManagementStudio查看触发器依赖关系•1)展开服务器。•2)分别展开“数据库”、“JWGL”、“表”、含触发器的表、“触发器”。•3)右击要查看依赖关系的触发器,然后单击“查看依赖关系”。•
4)查看完毕点击“确定”即可。86修改触发器1.使用T-SQL语句修改触发器使用T-SQL语句ALTERTRIGGER可以修改触发器,它的语法与CREATETRIGGER类似。具体语法形式如下:ALTERTRIGGERtrigger_nameONtabl
ename[WITHENCRYPTION]FOR{[DELETE][,][INSERT][,][UPDATE]}ASsql_statement在以上语法形式中:•●trigger_name:要更改的触发器名称。
•●tablename:指定触发器在其上执行的表或视图名字。•●WITHENCRYPTION:加密触发器的定义成本。•●FOR{[DELETE][,][INSERT][,][UPDATE]}:指定所更改的触发器将在发生哪些事件时被触发•●sql_statement:指定
触发器执行的SQL语句。872.使用SQLServerManagementStudio修改触发器使用SQLServerManagementStudio对触发器进行修改的具体步骤如下:•1)展开服务器。•2)分别展开“数据库”、“JWGL”、“表”、含触发器的表、“触发器”。•3)右击要
查看修改的触发器,然后单击“修改”即可。88删除触发器当不再需要某个触发器时,可将其删除。当触发器被删除时,它所基于的表和数据并不受影响。删除表将自动删除其上的所有触发器。1.使用T-SQL语句删除触发器使用DRO
PTRIGGER语句可以从当前数据库某个表中删除一个或多个触发器。其语法如下所示:DROPTRIGGER{trigger}[,...n]参数:•●trigger:要删除的触发器名称。•●n:表示可以删除多个触发器的占位符。【例12-7】
删除触发器student_delete,执行如下的语句。USEjwglIFEXISTS(SELECTnameFROMsysobjectsWHEREname='student_delete„ANDtype='TR„)DROPTRIGGERstudent_deleteGO892.使用
SQLServerManagementStudio删除触发器在SQLServerManagementStudio中,使用以下步骤删除触发器:•1)展开服务器。•2)分别展开“数据库”、“JWGL”、“表”、含触发器的表、“触发器”。
•3)右击要删除的触发器,然后单击“删除”。•4)在系统弹出的“删除对象”对话框上点击“确定”即可。903.4.3使用触发器的注意事项1.约束检查优于触发器检查如果在触发器表上有约束,那么这些约束在触发器执行前进行检查。如果操作与约束冲突,那么触发器将不执行。2
.触发器中的T-SQL限制触发器中不允许使用以下T-SQL语句:ALTERDATABASECREATEDATABASEDISKINITDISKRESIZEDROPDATABASELOADDATABASELOADLOGRECONFIGURERESTO
REDATABASERESTORELOG