数据库编程基础(存储过程和触发器)含应用举例

存储过程

存储过程概念

(百度百科)
存储过程(Stored Procedure)是在大型数据库系统中,一组为了完成特定功能的SQL 语句集,它存储在数据库中,一次编译后永久有效,用户通过指定存储过程的名字并给出参数(如果该存储过程带有参数)来执行它。存储过程是数据库中的一个重要对象。在数据量特别庞大的情况下利用存储过程能达到倍速的效率提升。

存储过程的作用

不使用存储过程时,所有的数据处理都在客户端完成;而使用存储过程时,可以使数据处理在服务器端完成。
可以避免在网络上传输大量无用的信息或原始数据,只需要传输调用存储过程的指令和数据库服务器返回的处理结果。
把完成某一数据库处理的功能设计为存储过程,则可以在各个程序中反复调用,从而减轻程序的编写工作量。
也可以利用存储程序间接实现一些安全控制功能。

创建和执行存储过程

创建存储过程的基本格式:
在这里插入图片描述
说明:
创建存储过程通常是在数据库设计和开发阶段完成的。
存储过程可以嵌套,即在一个存储过程中可以调用另外一个存储过程。
存储过程一般用来完成数据查询和数据处理操作;
在存储过程中不可以使用创建数据库对象的语句(如create table等各种create语句)。

执行存储过程的格式:
在这里插入图片描述
修改存储过程:
在这里插入图片描述
删除存储过程:
在这里插入图片描述

应用举例

--例1:使用简单过程。
--下面的存储过程将从表中返回所有职工信息(姓名、仓库号、工资、所在城市)。这个存储过程不使用任何参数。
CREATE PROCEDURE uspGetAllEmp  --  CREATE PROC uspGetAllEmp 
AS
    SELECT 姓名,仓库.仓库号,工资,城市 AS 所在城市
    FROM 仓储.仓库 JOIN 基础.职工 ON 仓库.仓库号=职工.仓库号
--例2:使用带有参数的简单过程。
--下面的存储过程只从表中返回指定城市的职工信息。该存储过程需要提供精确匹配的参数值。
CREATE PROCEDURE uspGetEmp1
@city char(10)
AS
    SELECT *
    FROM 基础.职工 
    WHERE 仓库号 IN
       (SELECT 仓库号 
        FROM 仓储.仓库
        WHERE 城市=@city)

--为了得到“北京”的职工信息,可通过以下方式执行存储过程uspGetEmp1:
EXECUTE uspGetEmp1 @city='北京'
EXECUTE uspGetEmp1 '北京'
--例3:使用带有参数和返回值的简单过程。
--下面的存储过程查询指定仓库订单金额大于指定值的订单数,查询结果通过RETURN语句返回:
CREATE PROCEDURE uspGetOrderNum
@whno char(6)='wh1',@sum money    --默认值为'wh1'
AS
 DECLARE @count int
 SELECT  @count=COUNT(*) 
 FROM 订货.订购单
 WHERE 金额>=@sum AND 经手人 IN
	(SELECT 职工号
	 FROM 基础.职工
	 WHERE 仓库号=@whno)
 RETURN @count

--下面的语句调用存储过程uspGetOrderNum查询WH1仓库金额大于1000的订单数:
DECLARE @count int
EXECUTE @count= uspGetOrderNum 'WH1',1000
PRINT 'WH1仓库金额在1000以上的订单数是:'+STR(@count)

DECLARE @count int
EXECUTE @count= uspGetOrderNum @sum=1000,@whno='WH1'
PRINT 'WH1仓库金额在1000以上的订单数是:'+STR(@count)
--例4:使用带有通配符参数的简单过程。
--下面的uspGetSup存储过程用于只从表中返回指定的一些供应商的信息(提供供应商名称中的关键字)。此存储过程通过参数的模式匹配完成查询,如果未提供参数,则返回全部供应商信息。
CREATE PROCEDURE 订货.uspGetSup
@sname varchar(20)='%'
AS
    SELECT * FROM 订货.供应商
    WHERE 供应商名 LIKE @sname

--以下执行存储过程的命令将返回供应商名称中含有“北京”的供应商信息:
EXECUTE 订货.uspGetSup @sname='%北京%'
--以下执行存储过程的命令将返回全部的供应商信息(没有提供参数):
EXECUTE 订货.uspGetSup

--例5. 使用 OUTPUT 参数
--指定供应商所经手订购单的数量和平均金额,一个参数传入指定供应商名,一个参数传出计算的平均金额,计算的订单数量用RETURN语句返回
--drop proc uspGetAvg
create proc uspGetAvg
@sname char(20),@avg money output
as
    declare @count int
	select @count=count(*),@avg=avg(金额)
	from 订货.订购单
	where 供货方=
		(select 供应商号
		from 订货.供应商
		where 供应商名=@sname)
	return @count

--调用
declare @avgout money ,@countout int
exec @countout=uspGetAvg @sname='华通电子公司',@avg=@avgout output
print '华通电子公司的订单数是:'+str(@countout)+',平均金额是:'+str(@avgout,6,2)

--1个输入参数,2个输出参数
create proc uspGetAvg2
	@sname char(20),
	@avg money output,
	@count int output
as
	select @count=count(*),@avg=avg(金额)
	from 订货.订购单
		where 供货方=
		(select 供应商号
		from 订货.供应商
		where 供应商名=@sname)

declare @avgout money ,@countout int
exec uspGetAvg2 @sname='华通电子公司',@avg=@avgout output,@count=@countout output
print '华通电子公司的订单数是:'+str(@countout)+',平均金额是:'+str(@avgout,6,2)

触发器

触发器的概念和用途

触发器可以看作是一类特殊的存储过程,它在满足某个特定条件时自动触发执行。触发器和存储过程同是提高数据库服务器性能的有力工具。
触发器是一种程序或是一种过程,它和存储过程一样是事先设计好存储在数据库中的,与存储过程不同的是触发器不需要专门调用或执行,触发器是在某个特定条件发生时自动触发执行的。
分为DML(数据操作语言)触发器、DDL(数据定义语言)触发器和LOGIN触发器
DML触发器在执行数据操作语言(update、insert和delete)时触发;
DDL触发器在执行数据定义语言时触发;
LOGIN触发器在有用户登录时触发。

DML触发器也是一个数据库对象,但DML触发器依附于表(或视图)。
DML触发器分为插入触发器、删除触发器和更新触发器三类

触发器的三个要素:
定义触发器的表(或视图)
激活触发器的数据操作语句
采取的动作

建立和删除触发器

建立:
在这里插入图片描述
删除:
在这里插入图片描述
比较for触发器和instead of触发器的区别

--instead of不能插入表中
create trigger wh_trigger1
on 仓储.仓库 
instead of insert
as 
	print 'instead of 触发器'
--使用触发器
insert into 仓储.仓库 values('WH8','杭州',450)

drop trigger wh_trigger1
--for可以把数据插入表中
create trigger wh_trigger1
on 仓储.仓库 
for insert 
as 
	print 'instead of 触发器'

deleted表和inserted表
当DML触发器激活时系统会自动产生两个特殊的临时表:deleted表和inserted表
当发生insert操作时新插入的记录也存储在inserted表
当发生deleted操作时被删除的记录也存储在deleted表
当发生update操作时修改前的旧记录也存储在deleted表、修改后的新纪录也存储在inserted表
可以使用deleted表和inserted表判断正在操作的记录是否符合要求,从而检查错误并采取相应的措施。
可以扩展表之间的参照完整性。
deleted表和inserted表只在触发器内可用,一旦触发器完成任务,这两个系统产生的临时表将自动删除。

扫描二维码关注公众号,回复: 11333192 查看本文章

触发器应用举例

CREATE TRIGGER reminder1
ON 仓储.库存
FOR UPDATE
AS
	DECLARE @amount int
	SELECT @amount=数量 FROM inserted
	IF @amount<5
		RAISERROR ('库存数量小于5',16,10)

UPDATE 仓储.库存 SET 数量=数量-3
where 仓库号='WH1' AND 器件号='P3'

猜你喜欢

转载自blog.csdn.net/LoraRae/article/details/106694139