第13章 数据库对象 13.1 存储过程8 |% S' ?' G* ~9 O8 p
13.1.1 存储过程基本概念! i F$ D: P3 L) ?) l( L/ t
1、 在关系数据库中,SQL语言是应用程序和数据库管理之间的主要编程接口;1 R& u- ~/ I6 p+ I3 t. q
2、 使用SQL语言编写代码时,可用两种方法存储和执行代码: b" \: }+ @9 R, D& Y5 X
(1) 在客户端存储代码,并创建向数据库管理系统发送SQL命令,并处理返回结果的应用程序;1 r2 U: f3 C. Q8 R1 W& @: |
(2) 将这些发送的SQL语句存储在数据库管理系统中,这些存储在数据库管理系统中的SQL语句就是存储过程,然后再创建执行存储过程并处理返回结果的应用程序。$ Y% }! x) r+ D/ k) T5 p
3、 使用存储过程的好处:: l1 N# s9 n$ d7 |
(1) 模块化程序设计:只需创建一次存储过程并将其存储在数据库中,以后就可以在应用程序中多次调用存储过程;
/ O. T$ }- Z5 o+ ~5 [) ? W (2) 提高性能:系统在创建存储过程时对其进行分析和优化,并在第一次执行时进行语法检查和编译,编译好的代码放入内存中,以后再执行此存储过程时,只需直接执行内存中的代码,从而提高代码的执行效率;
1 A# h, k; P: D) O( B; G% O (3) 减少网络流量:一个需要数百行SQL代码完成的操作现在只需一条执行存储过程的代码即可实现,因此,不再需要在网络中发送这些多语句;
! l( D0 k) n( w6 J (4) 可作为安全机制使用:, c5 R" v; c7 h7 a2 n* o
13.1.2 创建和执行存储过程4 `$ V! b3 V1 w
1、 创建存储过程的SQL语句为:CREATE PROCEDURE,语法格式为:( ~- h0 T- f w/ u+ x, o2 Y+ K2 I) h
CREATE PROCEDURE 存储过程名; [3 d. A( l3 u
[{@ 参数名 数据类型}[=default][OUTPUT]; l: |1 {9 m6 ? D% W6 W# h
][,…n]0 K! r, C ] M3 O5 X4 w- i) E
AS
# M; j- c4 E1 B* h SQL语句[…n]5 [. i, ]3 P7 a
其中:9 ~8 h2 v3 i, L# \% Q) f3 b+ x' u
(1) default:表示参数的默认值。如果定义了默认值,则在执行存储过程时,可以不必指定该参数的值,默认值必须是常量或NULL;
' b! n4 m" S: w J$ A/ S4 r (2) OUTPUT:表明参数是输出参数,该选项的值可以返回给存储过程的调用者。9 r- w3 T, u, }5 W6 E3 S6 ]
2、执行存储过程的SQL语句是EXECUTE,语法格式:5 q. w6 F, k/ W3 E
CREATE EXECUTE 存储过程名 [实参[,OUTPUT][,…n]]
' ?% _$ h& o6 S0 o1 W7 T 1、 执行有多个输入参数的存储过程时,参数的传递方式有两种:6 K+ u# j' `! y E ? M
(1) 按参数位置传递值:指执行存储过程的EXEC语句中的实参的排列顺序必须与定义存储过程时定义的参数的顺序一致;3 ~/ m/ p7 {5 c+ {
(2) 按参数名传递值:指执行存储过程的EXEC语句中要指明定义存储过程时指定的参数的名字以及此参数的值,而不关心参数的定义顺序。
$ b7 g+ F8 A7 |7 H 2、 注意:, y# z- n- N W
(1) 在执行有输出参数的存储过程时,执行语句中的变量名的后边要加上OUTPUT修饰符;
r# W+ Y* l. h' y& [) @ (2) 在调用有输出参数的存储过程时,与输出参数对应的是一个变量,此变量用于保存输出参数返回的结果;
* m7 P; j7 U z% x- N13.2 用户自定义函数
6 R& e+ Z+ H9 V' D 13.2.1 基本概念# @( h: L5 N7 O; t; A4 ^$ E
1、 用户定义函数可以扩展数据操作的功能,它在概念上类似于一般的程序设计语言中定义的函数。
7 W' c2 T6 f; C 13.2.2 创建和调用标量函数5 F: b6 r, ?& B3 u. b( l
标量函数—返回单个数据值的函数;
& {+ f8 u0 o$ Y- g! `$ e' j 1、定义标量函数
( ]* ~) e2 f0 [! k0 H& U7 ^7 f CREATE FUNCTION [拥有者名.] 函数名
$ L! c; z1 w$ Q+ @ ([{@ 参数名[AS]标量数据类型[=default]}[,…n]])8 X5 @7 k( r( F% | i# ?
RETURNS 返回值类型3 }& T# W- G5 N! n5 G3 c5 d5 a3 N
[AS]
- a% R! `* z' n! y BEGIN
0 A/ h/ c( l. e# n, |/ ~ 函数体
4 @: b$ W7 w' M& V- |& L* M RETURN 标量表达式, I( V6 V0 G( u( h
END
" j* T3 Y2 @6 J# k (1) 同存储过程一样,函数的参数也可以有默认值。
& m+ g6 t2 h* W+ L/ r (2) 标量表达式:指定标量函数返回的标量值。
+ c, D5 s- [6 i& f" a( l/ \! y: ]5 V 2、 调用标量函数:8 C6 B+ C. o- f3 S( C* H5 x: s8 k! D
当调用标量函数时,必须提供至少由两部分组成的名称:函数拥有者名和函数名。可在任何允许出现表达式的SQL语句中调用标量函数,只要类型一致;
0 l7 n2 m4 | C8 q/ p# |3 { 13.2.3 创建和调用内嵌表值函数
+ C- |6 G/ B; O1 b* @4 U, X$ h) R 1、 创建内嵌表值函数,其语法为:, s# ^2 H% l7 [$ o' |
CREATE FUNCTION [拥有者名.] 函数名+ j2 r! f! s, @. f" m# a
([{@ 参数名[AS]标量数据类型[=default]}[,…n]])4 B+ u5 j8 `9 `+ H) `
RETURNS 返回变量 TABLE + {8 n( f* B2 i9 K* V
[AS]9 ?& n/ Z+ o% U) t
BEGIN( b/ g2 B, M, {9 ]
函数体, @& x4 X4 e, V. E, C9 Z! L7 i
RETURN. e0 L5 e4 m; A5 d
END6 q v/ \$ t; L7 n5 A& C0 G% U$ _
::=({列定义|表约束}[,…n])
' G# |# L- Y2 ~$ b9 T; { e' f0 y 2、调用多语句表值函数
1 n' z: }* W9 n3 c) C+ l% V7 e# M \. x 多语句表值函数的返回值是一个表,因此对多语句表值函数的使用也是放在SELECT语句的FROM子句中。. ~% B5 Q& a. V
13.3 触发器
% q5 {3 c/ m9 G% S 13.3.1 触发器基本概念- ?: O7 B9 J5 f, y p/ I }! C& S/ J6 C
1、 触发器是一种特殊的存储过程,其特殊性在于它不需要由用户来调用,而是当用户对表中的数据进行UPDATE、INSERT或DELETE操作时自动触发执行;
4 M: ^6 D7 F% U8 Q+ M7 ]8 m8 S8 c 2、 触发器常用于下列场合:4 D2 W* Y* a& D1 K- x
(1) 完成比CHECK的约束更复杂的数据约束;/ |( ~# y" T* j
(2) 为保证数据库性能而维护的非规范化数据;
) D+ S+ r8 s) D* p3 J4 b- D9 e3 @3 I (3) 实现复杂的业务规则,可使业务的处理任务自动进行。7 E( w s* r' d: q, \7 Q6 O
13.3.2 创建触发器2 `9 k5 U+ k" j% M* _" \
1、 创建触发器的语句:CREATE TRIGGER,语法为:
0 Q7 N9 H# _5 _) m* e* ?+ I' A CREATE TRIGGER 触发器名称
1 p4 s; n3 _8 N7 e$ s ON {表名| 视图名} Z' ]7 U8 F4 T9 U: t9 g+ d
[WITH ENCRYPTION]7 ?1 p8 N2 x, ]5 \9 a9 J% k
{FOR |AFTER|INSTEAD OF}{[INSERT][,][DELETE][,][UPDATE]}
; @4 U' L& b4 b# P3 Y! F6 R5 B AS
; e( t# ^. j# q/ ]3 _ [{IF UPDATE(column)…}]
/ t# r" f2 f9 S0 ^ SQL语句+ z% {. G, P, S1 |6 Z- N; o
(1) 触发器名称在数据库中必须是惟一的; e# [; k# |6 ]7 ]6 f5 j/ e
(2) ON子句用于指定在其上执行触发器的表;
! Y3 \% [) h3 U% f (3) AFTER:指定触发器只有在引发的SQL语句中指定的操作都已成功执行,并且所有的约束检查也成功完成后,才执行此触发器,这种触发器称为后触发型触发器;* d' c" D: V# S& k/ a! C
(4) FOR:作用同AFTER;
/ T/ q% K5 A* G2 m
) \1 L7 `, X6 r3 g' s) a, [0 c) { (5) INSTEAD OF:指定执行触发器而不是执行引发触发器执行的SQL语句,从而替代触发语句的操作,这种触发器称为前触发型触发器; |