第四章习题参考答案
一、简答题
1、什么是存储过程?为什么要使用存储过程?
答:⑴、存储过程的定义:存储过程是存储在数据库服务器中的一组编译成单个执行计划的SQL语句。
原因:存储过程可以包含程序控制流、查询子句、操作字句,还可以接受参数、输出参数、返回单个值或多个结果集,使用存储过程有如下优点:
①、由于存储过程不像解释执行的SQL语句那样在提出操作请求时才进行语法分析和优化,因而运行效率高,它提供了在服务器端快速执行SQL语句的有效途径;
②、存储过程降低了客户机和服务器之间的通信量。客户机上的应用程序只要通过网络向服务器发出存储过程的名字和参数,就可以让RDBMS执行多条SQL语句,并执行数据处理,只将最终处理结果返回客户端;
③、方便企业实施规则。可以吧企业规则的运算程序写成存储过程放入数据库服务器,由RDBMS管理,既有利于集中控制,又方便维护。当用户规则发生变化时只要修改存储过程,无需修改其他应用程序。
2、试述触发器的概念和作用
答:概念:触发器是用户定义在关系表上的一类由事件驱动的特殊过程,也是一种保证数据完整性的方法。触发器也可以看做是一类特殊的存储过程,一旦定义,无须用户调用,任何对表的修改操作均由服务器自动激活相应的触发器。
作用:能够实现主键和外键所不能保证的复杂的参照完整性和数据的一致性。
3、什么是INSERTED表和DELETED表?试说明这两张表的结构。
答:INSERTED表:用于存储INSERT和UPDATE语句所影响的行的复本,执行INSERT和UPDATE语句时,新的数据行被添加到基本表中,同时这些数据行的备份被复制到INSERTED临时表中。
DELETED表:用于存储DELETE和UPDATE语句所影响的行的复本,执行DELETE或UPDATE语句时,行从触发器表中删除,并传输到DELETED表中,DELETED表和元数据表通常没有相同的行。
两张表的结构:①、这两个表都是逻辑表,并且是由系统管理的,存储在内存中,不是存储在数据库中。因此,不允许用户直接对其操作。
②、这两个表的结构与被该触发器作用的表有相同的表结构。它们是动态驻留在内存中,当触发器工作完成,它们也被删除。
③、这两个表主要保存因用户操作而被影响到的原数据值或新数据值,且是只读的,可以引用表中的数据,但不能向其写入内容。
4、什么是默认对象和默认值?他们有什么区别?
默认对象: 需要用create default语句进行定义,作为一种单独存储的数据库对象,它是独立于表的,删除表并不能删除默认对象,需要使用drop default语句删除默认对象。
默认值:是一种数据库对象,可以绑定到表的一列或多列上,也可以绑定到用户自定义的数据类型上,其作用类似于DEFAULT约束,当向表中插入数据,且没有为列输入值时,系统自动给列附一个默认值。与DEFAULT不同的是它的使用规则,通过一次定义,可以多次使用。在create table或alter table语句中定义后,被嵌入到定义的表结构中。也就是说,在删除表的时候默认约束也将随之被删除。
区别:默认值是用create table语句创建表时,使用default子句为表中的列提供默认值;
默认值对象是用create default语句来创建时,使用时须将它绑定到列上。
5、什么是规则?规则和CHECK约束有什么区别?
答:⑴、规则是数据库对存储在表中的列或用户自定义数据类型中的值的规定和限制,是单独存储的独立的数据库对象。
⑵、区别:①、CHECK约束是在使用CREATE TABLE 语句建表时指定的,而规则是作为独立于表的数据库对象,通过与指定表或数据类型绑定来实现完整性约束。
②、在一列上只能使用一个规则,但可以使用多个CHECK约束
③、规则可以应用于多个列,还可以应用于用户自定义的数据类型,而CHECK约束只能应用于它定义的列。
二、综合题
1.(1)
create procedure proc1
@pid char(4)
as
update products
set price=price+0.5
where pid=@pid;
go
1.(2)
create procedure proc2
@pid char(4),@pname char(6),@qty int,@price decimal(8,2)
as
insert into products(pid,pname,quantity,price)
values(@pid,@pname,@qty,@price);
go
1.(3)
create procedure proc3
@cname char(8),@pname char(6),@qty int output
as
select @qty=sum(qty)
from customers c,orders o,products p
where c.cid=o.cid and o.pid=p.pid and cname=@cname and pname=p.pname;
go
2.(1)
create trigger tr_insprod
on products
for insert
as
delare @price decimal(8,2),@pid char(4)
select @pid=pid,@price=price from inserted;
if @price<0.5
begin
update products
set price=0.5
where pid=@pid
RAISERROR('产品单价不得低于0.50元!',16,10);
end
go
2.(2)
create trigger tr_updord
on orders
for update
as
delare @price decimal(8,2),@o_id char(4),@pid char(4)
if update(qty)
begin
select @pid=pid,@o_id=ord_id from inserted;
select @price=price from products where pid=@pid;
update orders
set amount=@qty*@price
where ord_id=@o_id;
end
go