SQL基础学习5-存储过程与触发器

SQL基础学习4-存储过程与触发器

  • 存储过程
    • 存储过程的概述
    • 创建和执行用户存储过程
      • 不带参数的存储过程
      • 带输入参数的存储过程
      • 带输出参数的存储过程
      • 管理存储过程
    • 系统存储过程和扩展存储过程
      • 系统存储过程
      • 扩展存储过程
    • 存储过程的应用
  • 触发器
    • 触发器概述
    • 后触发型触发器)
    • 前触发型触发器
    • 管理触发器
    • DDL触发器

存储过程

存储过程的概述

概念:
存储过程是一组能够完成特定功能的Transact-SQL语句集,经编译后存储在数据库中,用用户通过过过程名和给出的参数来调用它。有两种方法存储和执行代码

  1. 在客户端存储代码,然后创建向 SQL Server 发送SQL命令(或SQL语句)并处理返回结果的应用程序;
  2. 将发送的SQL语句存储在服务器端的数据库中,然后由客户端应用程序调用执行这些代码。这些存储在服务器端数据库中供客户端调用执行的SQL语句就是存储过程。

功能

  1. 接受输入参数并以输出参数的形式将多个值返回给调用过程。
  2. 包含执行数据库操作(包括调用其它过程)的多句编程语句。
  3. 向调用过程返回状态值,以表明成功或失败(以及失败原因)。

存储过程的特点

  1. 允许模块化程序设计
  2. 改善性能,执行速度快
  3. 能够有效减少网络流量
  4. 可作为安全机制使用,提高数据库的安全性

存储过程的分类
分为三类:系统存储过程,用户自定义存储过程,扩展存储过程。

创建和执行用户存储过程

创建存储过程

CREATE PROC[ EDURE ] 存储过程名 
[ { @参数名  数据类型 } [ = default ] [OUTPUT] 
] [ , ... n ]
[WITH ENCRYPTION]
[WITH RECOMPILE]
  AS  
    SQL语句 [ ... n ]

@参数名称:存储过程中可以没有参数,也可以声明一个或多个参数。参数名称必须以@作为第一字符。参数后面带OUTPUT,表示为输出参数
WITH ENCRYPTION:对存储过程加密,其他用户无法查看存储过程的定义。
WITH RECOMPILE:每次执行该存储过程时都重新编译。
default:表示参数的默认值。如果定义了默认值,则在执行存储过程时,可以不必指定该参数的值。
OUTPUT:表明参数是输出参数。使用 OUTPUT 参数可将信息返回给调用者。

按定义中的参数形式,可以把存储过程分为不带参数的存储过程、带输入参数的存储过程和带输出参数的存储过程3类。

不带参数的存储过程

  1. 创建与执行不带参数的存储过程
CREATE PROCEDURE 存储过程名  --定义过程名
[WITH ENCRYPTION]
[WITH RECOMPILE]
AS
  sql_statement    --过程体

--执行存储过程
EXECUTE  存储过程名

存储过程创建成功后,用户可以执行存储过程来检查存储过程的返回结果。

带输入参数的存储过程

  1. 创建与执行带输入参数的存储过程
CREATE PROCEDURE 存储过程名
@参数名称  参数数据类型 [=参数默认值]
AS
  sql_statement
--为测试过程体的正确性  
--如在过程体sql_statement中
SELECT Sname,Sdept
FROM Student
WHERE Sno=@sno --假定输入参数(参数对应的属性=@定义的参数) 

--执行存储过程
--1)使用参数名传递参数值
EXECUTE 存储过程名  @参数名=参数值
--2)按位置传递参数值
EXECUTE [参数值1,参数值2···]

当使用按位置传递参数值时,可以忽略允许空值和具有默认值的输入参数值,但不能破坏输入参数的顺序

带输出参数的存储过程

  1. 创建与执行带输出参数的存储过程
    带输出参数的存储过程可以返回一个或多个值。输出参数必须位于所有输入参数声明之后。
@参数名 数据类型[=默认数值]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

管理存储过程

  1. 查看存储过程
    存储过程被创建之后,它的名称被存储在系统表sysobjects中,它的源代码被存放在系统表sysobjects中。
    (1)sp_help用于显示存储过程的参数及其数据类型。
    (2)sp_helptext用于显示存储过程的源代码(如果用了WITH ENCYPTION将无法查看存储过程的源代码)
sp_help [[@objname=]存储过程名]
sp_helptext [[@objname=]存储过程名]
  1. 删除存储过程
DROP PROCEDURE 存储过程名
  1. 修改存储过程
    如果要修改存储过程名,则可以先删除存储过程,再重建;或者使用ALTER 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:设置一系列字符和值的格式并将其存储到字符串输出参数中。每个格式参数都用相应的参数替换。

存储过程的应用

在一个数据库中创建存储过程需要考虑以下因素

  1. 一个存储过程完成一个任务
  2. 不要使用“sp_”来命名用户存储过程。
  3. 可以使用WITH ENCRYPTION加密存储过程,以免存储过程的源代码被人查阅
  4. 在存储过程的开始位置执行SET语句
  5. 在服务器创建、测试存储过程。

触发器

触发器概述

触发器是一种特殊的存储过程。一般存储过程通过存储过程名可以直接调用而执行,但触发器不需要用EXEC命令调用,而是在某个指定的事件执行时激活。当用户对表中的数据进行UPDATE、INSERT或DELETE操作时自动触发执行
通常用于保证业务规则和数据完整性
使用户可以用编程的方法来实现复杂的处理逻辑和商业规则,增强了数据完整性约束的功能。

创建触发器

CREATE TRIGGER 触发器名称
ON {表名 | 视图名}
{ FOR | AFTER | INSTEAD OF } 
{ [ INSERT ] [ , ] 
  [ DELETE ] [ , ]
  [UPDATE ] }
AS 
  SQL 语句

注意

  1. 在一个表上可以建立多个触发器
  2. 对于AFTER型的触发器,可以在同一种操作上建立多个触发器;不可以定义在视图上.
  3. 对于INSTEAD OF型的触发器,在同一种操作上只能建立一个触发器。
  4. 不允许在触发器中创建和更改数据库以及数据库对象的语句、以及所有的DROP语句。

INSERTED和DELETED
在进行数据更新操作时,会产生两个临时的、用于记录更改的前后的表。这两个表的结构与创建触发器的表的结构相同。触发器类型不同,创建的两个临时表的情况和记录都不同。

操作类型 INSERTED DELETED表
INSERT 插入的记录 不创建
DELETE 不创建 删除的记录
UPDATE 修改后的记录 修改前的记录

INSERTED表保存了INSERT操作中新插入的数据和UPDATE操作中更新后的数据;
DELETED保存了DELETE操作删除的数据和UPDATE操作中更新前的数据。

后触发型触发器)

  1. 创建insert触发器
    当向表中插入记录时,insert触发器被激活.一般情况下,这种触发器常用来检查插入的数据是否满足要求,确保数据完整性。
创建一个触发器,当向学生表插入数据时,
发出消息提示“插入一条记录”*
--(1)创建触发器
CREATE TRIGGER tr_instu
ON Student
FOR INSERT
AS 
  begin
  PRINT'插入一条记录'
  (其中可能有rollback情况:回滚,不允许插入新的行)
  end
--(2)测试触发器
Insert into student values ('95009', '31',97)

说明:触发器与引发触发器执行的操作共同构成了一个事务。
事务的开始是引发触发器执行的操作,事务的结束是触发器的结束。

  1. 创建delete触发器
    delete触发器通常用于防止那些确实要删除.但是可能会引起数据一致性问题的情况,一般是那些在其他表的外部键;另一方面用于级联删除操作,即在删除父记录的同时级联删除了记录。
/*创建一个触发器,如果要删除学生表中的记录,
则将该记录学号对应的选秀表中的选秀记录一起删除。*/
--(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'
  1. 创建update触发器
    update触发器的工作相当于删除一条旧的记录,插入一条新的记录。因此,可以将update语句分为两步操作,即捕获原始行DELETE语句和捕获更新行的INSERT语句。当执行时,原始行被移入DELETE表,更新行被移入INSERT表。
例题
--创建一个名为“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触发器

DDL 触发器常用于如下的情况。

  1. 防止对数据库架构进行某些更改。
  2. 以响应数据库架构中的更改。
  3. 记录数据库架构中的更改或事件
CREATE TRIGGER  触发器名 
ON  { ALL SERVER | DATABASE } 
[WITH  ENCRYPTION ]  
{ FOR | AFTER } { DDL事件} [ ,...n ]
AS
  sql_statement 

你可能感兴趣的:(SQL基础学习,sql,大数据,sqlserver)