第13章 数据库对象
13.1 存储过程的:SQL语句和控制流语句的预编译集合,应用程序可通过调用方法来执行
优点:模块化程序设计;提高性能;减少网络流量;可作为安全机制使用
13.2 带有多个参数并有默认值及输出参数的存储过程示例:
CREATE PROCEDURE p_Example
@area varchar(20) = ‘武汉大学’,@Price money,@Sum int output
AS
SELECT/UPDATE/INSERT/DELETE……
SET @Sum = …。.
应用程序中执行的SQL语句:
Declare @res int
EXECUTE p_Example ‘武汉大学信息学部’,1000,@res output
或者 EXECUTE p_Example @Price =1000,@res output
13.3 用户自定义函数:标量函数(返回单值,非text、Image类型,任何允许出现表达式的地方)、内嵌表值函数(返回一个表,放在查询语句的From子句中)、多语句表值函数(返回一个可自定义的表,也放在查询语句的From子句中,视图和存储过程的结合)
13.4 标量函数救示例:根据指定的商品类别查询该类的商品个数。
CREAT FUNCTION dbo.f_GoodsCount(@class varchar(10))
RETURNS int
AS
BEGIN
DECLARE @x int
SELECT @x=count(*) From T_GoodsClass a JION T_Goods b
ON a.GoodClassID = b.GoodClassID
WHERE GoodClassName = @class
RETURN @x
END
调用:SELECT dbo.f_GoodsCount(‘服装’) 或者
SELECT GoodsName AS 商品名,dbo.f_GoodsCount(‘服装’) AS 种类数 From …。
13.5 内嵌表值函数的不同之处在于RETURNS 后只能是table,RETURN后面只能是单个的 SELECT语句,没有相关联的返回变量也没有函数体。调用时放在查询语句的FROM子句中。
13.6 触发器是一种不需要由用户来调用的存储过程,当用户对表进行UPDATE、INSERT或DELETE操作时自动触发执行。作用:保证业务规则和数据完整性。优点:用编程方法来实现复杂的处理逻辑和业务规则,增强数据完整性约束。
13.7 触发器适用场合:比CHECK语句更复杂的数据约束(可引用其他表中的列);为保证数据库性能而维护的非规范化数据(如增加统计总值的列);实现复杂的业务规则
13.8 AFTER/FOR:后触发型触发器,可在同一操作上建立多个;INSTEAD OF:前触发型,在同一操作上只能建立一个。所有的涉及对数据库对象操作的语句均不允许出现在触发器中。
13.9 DELETED表:存储UPDATE和DELETED操作语句所影响行的更新前的旧数据;
INSERTED表:存储UPDATE和INSERT操作语句所影响行的更新后的新数据。
13.10 维护数据操作完整性的后触发器示例:销售量大于库存量则撤销当前销售,小于时则在插入销售单据明细时同时修改库存量。
Create Trigger OperatonCon
ON T_SaleDetail FOR INSERT
AS
IF EXISTS(Select * From inserted a Jion T_Goods b
ON a.GoodsID = b.GoodsID WHERE a.Quanity 》 b.TotalCharge)
BEGIN
ROLLBACK
PRINT ‘此商品库存量小于此次销售数量’
END
ELSE
UPDATE T_Goods SET TotalCharge = TotalCharge –
(SELECT Quanity From inserted)
13.11 维护不同列之间取值完整性的后触发器示例:保证商品表中的单价与价格变动表中一致
CREATE TRIGGER PriceConstraint
ON T_PriceHistory FOR INSERT, UPDATE
AS
DECLARE @newprice money
SELECT @newprice = SalePrice From inserted
UPDATE T_Goods SET SaleUnitPrice = @newprice
WHERE GoodsID IN (SELECT GoodID From inserted )
13.12 前触发器指定执行触发器而不执行引发触发器的SQL语句,因此,如果数据操作满足完整性约束则在触发器中必须重新执行这些数据操作语句。
前触发器示例:保证销售单据中的会员卡是有效日期内的会员卡:
CREATE TRIGGER CardValid
ON T_SaleDetail INSTEAD OF INSERT, UPDATE
AS
IF NOT EXISTS (SElETCT * From inserted a JOIN T_Card b ON a.CardID=b.CardID
WHERE a.SalDate NOT BETWEEN b.StartDate AND b.EndDate)
INSERT INTO T_SaleDetail SELECT * From inserted (若满足条件此语句重新执行)
13.13 用SQL语句修改存储过程、用户自定义函数、触发器的语法与创建基本一致,只是将CREATE改为了ALTER。(查询分析器中实现)