概念:
存储过程是一组能够完成特定功能的Transact-SQL语句集,经编译后存储在数据库中,用用户通过过过程名和给出的参数来调用它。有两种方法存储和执行代码
功能
存储过程的特点
存储过程的分类
分为三类:系统存储过程,用户自定义存储过程,扩展存储过程。
创建存储过程
CREATE PROC[ EDURE ] 存储过程名
[ { @参数名 数据类型 } [ = default ] [OUTPUT]
] [ , ... n ]
[WITH ENCRYPTION]
[WITH RECOMPILE]
AS
SQL语句 [ ... n ]
@参数名称
:存储过程中可以没有参数,也可以声明一个或多个参数。参数名称必须以@作为第一字符。参数后面带OUTPUT,表示为输出参数
WITH ENCRYPTION
:对存储过程加密,其他用户无法查看存储过程的定义。
WITH RECOMPILE
:每次执行该存储过程时都重新编译。
default
:表示参数的默认值。如果定义了默认值,则在执行存储过程时,可以不必指定该参数的值。
OUTPUT
:表明参数是输出参数。使用 OUTPUT 参数可将信息返回给调用者。
按定义中的参数形式,可以把存储过程分为不带参数的存储过程、带输入参数的存储过程和带输出参数的存储过程3类。
CREATE PROCEDURE 存储过程名 --定义过程名
[WITH ENCRYPTION]
[WITH RECOMPILE]
AS
sql_statement --过程体
--执行存储过程
EXECUTE 存储过程名
存储过程创建成功后,用户可以执行存储过程来检查存储过程的返回结果。
CREATE PROCEDURE 存储过程名
@参数名称 参数数据类型 [=参数默认值]
AS
sql_statement
--为测试过程体的正确性
--如在过程体sql_statement中
SELECT Sname,Sdept
FROM Student
WHERE Sno=@sno --假定输入参数(参数对应的属性=@定义的参数)
--执行存储过程
--1)使用参数名传递参数值
EXECUTE 存储过程名 @参数名=参数值
--2)按位置传递参数值
EXECUTE [参数值1,参数值2···]
当使用按位置传递参数值时,可以忽略允许空值和具有默认值的输入参数值,但不能破坏输入参数的顺序
@参数名 数据类型[=默认数值]OUTPUT
--执行存储过程
EXECUTE 存储过程名
[[@参数名称=]{参数值|@变量[OUTPUT]|[默认值]}][,···n]
为了接收某一存储过程的返回值,在调用该存储过程的程序中,也必须声明作为输出的传递参数。这个输出参数可声明为局部变量,用来存放返回值。如下面这道例题
创建一个存储过程,用于计算两个数的乘积,且可以将计算结果通过输出参数返回给调用者。
CREATE PROCEDURE P_Sum
@var1 int,@var2 int,
@var3 int OUTPUT
AS
SET @var3 = @var1 * @var2
--执行创建的存储过程P_Sum
DECLARE @res int
EXECUTE P_Sum 3,6,@res OUTPUT
PRINT @res
sp_help [[@objname=]存储过程名]
sp_helptext [[@objname=]存储过程名]
DROP PROCEDURE 存储过程名
ALTER PROCEDURE 存储过程名
[{@参数名称 参数数据类型} [=参数的默认值]
[OUTPUT]
[WITH ENCRYPTION]
[WITH RECOMPILE]
AS
sql_statement
系统表时SQL Server用来存放各种对象信息的地方,而系统表存放在master和msdb数据库中,且大部分以“sp_”开头。系统表中存放的信息大部分是数值数据。
sp_tables
:返回可在当前环境中查询的表和视图的列表。
sp_stored_procedures
:返回当前环境中的存储过程列表。
sp_rename
:在当前数据库中更改用户创建对象的i名称,此对象可以是表、索引、列和别名数据类型等。
sp_renamedb
:更改数据库的名称。
sp_help
:用于查看数据库对象、用户定义数据类型或SQL提供的数据类型。
sp_helptext
:返回用户定义的规则、默认值、未加密的SQL存储过程、用户定义函数、触发器、计算列、CHECK约束、视图或系统对象(如系统存储过程)的内容。
sp-who
:提供有关Microsoft SQL Server Database Engine实例中当前用户和进程的信息。
sp_password
:为Microsoft SQL Server登录名添加或更改密码。
使用其能够在程序设计语言中创建自己的外部例程。其是SQL Server实例可以动态加载和运行的DLL,扩展了SQL Server的性能,常以“xp_”开头。
xp_cmdshell
:用来运行平常在命令提示符下执行的程序,如DIR(显示目录)和MD(更改目录)命令等。
xp_sscanf
:将数据从字符串读入每日个人格式参数所指定的参数位置。
xp_sprintf
:设置一系列字符和值的格式并将其存储到字符串输出参数中。每个格式参数都用相应的参数替换。
在一个数据库中创建存储过程需要考虑以下因素
触发器是一种特殊的存储过程。一般存储过程通过存储过程名可以直接调用而执行,但触发器不需要用EXEC命令调用,而是在某个指定的事件执行时激活。当用户对表中的数据进行UPDATE、INSERT或DELETE操作时自动触发执行。
通常用于保证业务规则和数据完整性。
使用户可以用编程的方法来实现复杂的处理逻辑和商业规则,增强了数据完整性约束的功能。
创建触发器
CREATE TRIGGER 触发器名称
ON {表名 | 视图名}
{ FOR | AFTER | INSTEAD OF }
{ [ INSERT ] [ , ]
[ DELETE ] [ , ]
[UPDATE ] }
AS
SQL 语句
注意:
INSERTED和DELETED
在进行数据更新操作时,会产生两个临时的、用于记录更改的前后的表。这两个表的结构与创建触发器的表的结构相同。触发器类型不同,创建的两个临时表的情况和记录都不同。
操作类型 | INSERTED | DELETED表 |
---|---|---|
INSERT | 插入的记录 | 不创建 |
DELETE | 不创建 | 删除的记录 |
UPDATE | 修改后的记录 | 修改前的记录 |
INSERTED表
保存了INSERT操作中新插入的数据和UPDATE操作中更新后的数据;
DELETED
保存了DELETE操作删除的数据和UPDATE操作中更新前的数据。
创建一个触发器,当向学生表插入数据时,
发出消息提示“插入一条记录”*
--(1)创建触发器
CREATE TRIGGER tr_instu
ON Student
FOR INSERT
AS
begin
PRINT'插入一条记录'
(其中可能有rollback情况:回滚,不允许插入新的行)
end
--(2)测试触发器
Insert into student values ('95009', '31',97)
说明:触发器与引发触发器执行的操作共同构成了一个事务。
事务的开始是引发触发器执行的操作,事务的结束是触发器的结束。
/*创建一个触发器,如果要删除学生表中的记录,
则将该记录学号对应的选秀表中的选秀记录一起删除。*/
--(1)创建触发器
CREATE TRIGGER Delete_sc
ON student
FOR DELETE
AS
DELETE sc
WHERE sc.sno in(SELECT sno
FROM deleted)
--(2)测试触发器
DELETE FROM student WHERE sno= ' 95005'
例题
--创建一个名为“Update_course”的触发器,如发现课程表的学分列发生变化时,激活触发器,在屏幕上显示“Hello,课程表学分已被修改,触发器起到作用"
Create trigger Update_course
on course
for update
as
if update(credit)
begin
select * from course
print 'Hello,课程表学时已被修改,触发器起到作用'
end
--测试:
update course
set credit=3 where cno='2'
前触发器指指定执行触发器而不是执行引发触发器执行的SQL语句,从而替代引发语句的操作。 INSERT 语句,将直接执行这个触发器。而不是等你 INSERT 语句执行完了,数据写到表里面了以后,才触发。
--创建一个触发器,当添加一个新学生的时候,默认在sc表中插入这个学生选修1号课程,成绩为空。
Create trigger cha_sc
on student
for insert
AS
declare @cc char(5)
select @cc=sno from inserted
insert into sc
values(@cc,'1',null)
查看和更改触发器
1.查看触发器
在对象资源管理器中,通过展开某个表下的“触发器”节点,可以看到定义在该表上的全部触发器。
sp_help
:显示触发器的所有者和创建时间
sp_helptext
:显示触发器的源代码
sp_depends
:显示该触发器参照的对象清单
2. 修改触发器
使用ALTER语句
ALTER TRIGGER 触发器名
ON 表名或视图名
[WITH ENCRYPTION]
{FOR|AFTER |INSTEAD OF}
{[ DELETE ][,][INSERT][,][UPDATE]}
AS
sql_statement
3.删除触发器
DROP TRIGGER 触发器名 [ ,...n ]
4.禁用触发器
禁用后,触发器仍然存在于该表上
DISABLE TRIGGER {ALL| 触发器名[,···n]}
ON {object_name | DATABASE | ALL SERVER}
5.启用触发器
已禁用的可以重新启用
ENABLE TRIGGER {ALL | 触发器名[,···n]}
ON {object_name | DATABASE | ALL SERVER}
DDL 触发器常用于如下的情况。
CREATE TRIGGER 触发器名
ON { ALL SERVER | DATABASE }
[WITH ENCRYPTION ]
{ FOR | AFTER } { DDL事件} [ ,...n ]
AS
sql_statement