版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
过程与函数块不能在数据库中。不能从其他PL/SQL块中进行调用。过程、函数、包和触发器都是带名块,可以在数据库中,可以在需要的任何地方运行。7.1
使用过程7.1.1创建过程例:--addstud.sqlCreate
or
replace
procedure
addnewstudent(p_
name
students.
_name%type,p_lastname
students.last_name%type,p_major
students.major%type)asbegininsert
into
students(id,
_name,last_name,major,current_credits)name,values
(student_sequence.nextval,p_p_lastname,p_major,0);commit;End
addnewstudent;在创建了这个块以后,
可以从另一个块中调用他,如:Beginaddnewstudent(‘david’,’dinsmore’,’music’);End;首先使用create
or
replace
procedure语句创建过程
addnewstudent。创建过程的时候,他首先被编译,然后以编译过的形式在数据库中。以后可以从其他的PL/SQL块调用这段被编译过的代码。在调用过程的时候可以传递参数一个过程调用本身就是一个PL/SQL语句。该调用不作为表达式的一部分。当调用过程的时候,控制将转给该过程的第一条可执行语句。当过程结束时,控制重新交还给紧挨着该过程调用的下一个语句。过程是一个PL/SQL块,带有部分、执行部分和异常部分,只有执行部分是必须的。]
as
|
is创建过程语法如下:create
or
replace
procedure
过程名[
参数名1 in
|out
|
in
out
类型名,参数名2
过程体创建过程是DDL语句,因此,在语句之后有一条隐含的commit语句。1.参数的模式及约束例:调用addnewstudent过程块--callproc.sqlDeclarev_new name
students.
_name%type:=‘margeret’;v_lastnmae
students.last_name%type:=‘mason’;v_major
students.major%type:=‘history’;Beginaddnewstudent(v_
name,v_lastname,v_major);End;在上面的块中v_
name,v_lastname,v_major
是实参,
p_
name,p_lastname,p_major是形参,调用时,实参的值赋给形参。形参可以有三种模式-in、out、in out。没有指定形参的模式时,形参缺省的模式是in。下例给出了每种模式之间的差异:Create
or
replace
procedure
modetest(p_inparameter innumber,p_outparameterout
number,p_inoutparameter
in
out
number)
isv_loactionvariable
number;Beginv_loactionvariable:=p_inparameter;--合法p_inparameter:=7;--
p_outparameter:=7--合法v_loactionvariable:=p_outparameter;----合法V_locationvariable:=p_inoutparameter;P_inoutparameter:=7;--合法End
modetest;**select into
和fetch
into也可以在into子句中进行赋值,这些变量也遵循同样的规则的例子。例:下面的例子是对modetest的合法调用Declarev_number1
number:=2;v_number2
number:=3;Beginmodetest(12,v_number1,v_number2);End;如果用文字替换v_variable2,就会得到下面Declarev_number1
number;Beginmodetest(12,v_number1,11);End;模式说明in当调用过程时,实参的值被传递给形参。在该过程内
部,形参被认为是只读的,不能被改变。过程结束时,实参的值不会被改变out在调用过程时,实参所拥有的任何值都会被忽略。在过程,形参被认为是只写的,只能进行赋值,不能从中数据。当过程结束时,形参的值被赋给实参。Inout这种模式是in
和out
的组合。在调用过程时,实参的值被赋给形参。在过程,形参可以被读出,也可以被赋值。当过程结束时,形参的值被赋给实参。**如果过程没有参数,在过程说明和调用时都不需要括号了。此规则对函数同样适用。2.
过程主体过程主体是一个拥有
、执行和异常部分的PL/SQL块。部分在is或as和begin之间,执行部分在begin和exception之间,异常部分在exception和end之间。过程的结构是这样的:Create
or
replace
procedure
过程名as/*
部分*/Begin/*执行部分*/Exception/*异常部分*/End
过程名;对形参的约束在调用一个过程中,不仅实参的值被传递给形参,而且对变量的限制也传递进去。因此在过程
中限制char,varchar2参数的长度,number参数的精度和刻度都是
的。如:下面的过程
是
的:Ceate
or
replace
procedure
parameterlenth(p_parameter1
in
out
varchar2(10),p_parameter2
in
out
number(3,2)
)asBeginp_parameter1:=‘a1bcdefghijklmn’;p_parameter2:=12.3;End
parameterlength;这个过程的正确
应该是Create
or
replace
procedure
parameterlength(p_parameter1
in
out
varchar2,p_parameter2
in
out
number)
asBeginp_parameter1:=‘bcdefghijklmnop’;p_parameter2:=12.3;End
parameterlength;对p_parameter1和p_parameter2的限制是传递给的实参的限制。例:以下代码调用过程parameterlength过程Declarev_variable1
varchar2(40);v_variable2
number(3,4);Beginparameterlength(v_variable1,v_variable2);End
;Declarev_variable1
varchar2(10);v_variable2
number(3,4);Beginparameterlength(v
_variable1,v_variable2);End
;上面的块和前面的块的唯一不同是v_variable1,parameterlength将一个长度为15的字符串赋值给p_parameter1会产生错误。**为避免发生以上的错误,请在创建过程的时候对实际参数的限制要求给予详细的文档说明。文档注释应该包括该过程要用什么样的处理和参数。%type和过程参数:取得对形参唯一限制的方法是用%
type。如果使用了%type对形参进行说明,而基准类型是受限的,则该限制将作用于形参而不是实际参数。如:Create
or
replace
procedure
parameterlength(p_parameter1
in
out
varachr2,p_parameter2
in
out
studets.current_credits%type)
asBeginp_parameter2:=12345;End
parameterlength;那么p_parameter2将被限制为精度为3。这是因为current_credits列的精度。甚至
采用足够精度的实参调用parameterlength时,处理中所采用的也是形参的精度。例:Declarev_variable1
varchar2(1);v_variable2
number;Beginparameterlength(v_variable1,v_variable2);--产生ora-6502错误。End;位置标识法和带名标识法到目前为止,实参都是通过位置和形参相对应的。假设有下面的过程
:Create
or
replace
procedure
callme(p_parametera
varchr2,p_parameterb
number,p_parameterc
boolean,p_parameterd
date)
asBeginnull;End
callme;以及象下面这样的调用块:Declarev_variable1
varchar2(10);v_
variable2
number(7,6);v_variable3
boolean;v_variable4
date;Begincallme(v_variable1,v_variable2,v_variable3,v_variable4);End;实参v_variable1与形参p_parametera对应,v_variable2与p_parameterb对应,v_variable3与p_parameterc对应,v_variable4与p_parameterd对应。这就是所谓的位置标识法。也可以使用带名标识法来调用过程Declarev_variable1
varchar2(10);v_variable2
number(7,6);v_variable3
boolean;v_variable4
date;Begincallme(p_parametera=>v_variable1,p_parameterb=>v_variable2,p_parameterc=>v_variable3,p_parameterd=>v_variable4);End;在带名标识法中形参和实参都被每个参数所包含,这样我们可以重新调整参数的顺序。如果需要的话,下面的块也可以使用相同的参数调用callme。Declarev_variable1
varchar2(10);v_variable2
number(7,6);v_variable3
boolean;v_variable4
date;Begincallme(p_parameterb=>v_variable2,p_parameterc=>v_variable3,p_parameterd=>v_variable4,p_parametera=>v_variable1);End;如果需要的话,在同一个调用中位置标识法和带名标识法可以混合使用。下面的块说明了这种方法。Declarev_variable1
varchar2(10);v_variable2
number(7,6);v_variable3
boolean;v_variable4
date;Begincallme(v_variable1,v_variable2,p_parameterc=>v_variable3,p_parameterd=>v_variable4);End;我通常使用带名标识法,因为更愿意编写简洁的代码。但是如果过程使用太多的参数(>10),则使用带名标识法更好。**使用单个记录取代太多的参数参数缺省值如果一个参数拥有缺省值,则他不必从调用环境中传入数值。如果他被传递进来数值的话,那么他所使用的是实际的值,而不是缺省的值。参数的缺省值通过以下语法说明:Parameter_name
〔mode〕parameter_type[:=|
default]initial_value例:Create
or
replace
procedure
addnewstudent(p_ name
students.
_name%type;p_lastname
students.last_name%type;p_major
students.major%type
default
‘economics’)
asBegininsert
into
students
values
(student_sequence.nextval,p_
name,p_lastname,p_major,0);End
addnewstudent;如果在调用过程中p_major没有找到实参,就用缺省值economics代替可以通过位置标识法做到这点,如:beginaddnewstudent(‘babara’,’blues’);End;或者使用带名标识法:Beginaddnewstudent(p_
name=>’babara’,p_lastname=>’blues’);End;如果使用的是位置标识法,没有相关联实际参数,而使用缺省值的所有参数都必须位于参数表的末尾。例:Create
or
replace
procedure
defaulttest(p_parametera
number
default
10,p_parameterb
varchar2
default
‘abcdef’,p_parameterc
date
default
sysdate)
asBeginDbms_output.put_line(‘a:’||p_parametera||’b:’);End
defaulttest;如果
想要仅p_parameterb使用缺省值,为p_parametera和p_parameterb指定值,则应使用带名标识法:Begindefaulttest(p_parametera=>7,p_parameterc=>’30-dec-95’);End;在使用位置标识法的时候,如果
想要p_parameterb使用缺省值,则p_parameterc也要使用缺省值。例:Begindefaulttest(7);End;7.1.2
调用过程Oracle允许在sql*plus、oracleforms和其它支持oracle的编程环境中调用过程。但是连接oracle的用户必须有对过程的执行权限。Grant
execute
on
procedurename
to
username;过程的执行权限。用于为用户赋予7.1.3
重新编译过程7.2
使用函数创建函数函数十分类似于过程,都可以在块内被或在数据库的。但是过程调用本身是一个语句,函数调用是表达式的一部分,不是语句。例:指定的班级有90%以上是满的返回true,否则返回false。Create
or
replace
function
almostfull(p_department
classes.department%type,p_course
classes.cousr%type)Return
boolean
isV_currentstudents
number;v_maxstudents
number;v_returnvalue
boolean;v_fullpercent
constant
number:=90;Beginselect
current_students,max_studentsinto
v_currentstudents,v_maxstudentsfrom
classeswhere
department=p_departmentand
course=p_course;If
(v_currentstudents/v_maxstudents*100)>v_fullpercent
thenv_returnvalue:=true;elsev_returnvalue:=false;end
if;return
v_returnvalue;End
allmostfull;可以用下面的PL/SQL块调用他Declarecursor
c_classes
isselect
department,course
from
classes;Beginfor
v_classesrecord
in
c_classes
loopifallmostfull(v_classesrecord.department,v_classesrecord.course)
theninsert
into
temp_table (char_col)
values(v_classesrecord.department
||
‘
‘||v_classesrecord.course
||
‘is
almost
full’);end
if;end
loop;End;函数语法Create
or
replace
function
function_name[
(
argument
[in
|
out
|in
out
]
type,…)]return
return_type [is
|
as
]Fuction_body与过程类似,参数是可选的。因此可以不必在函数和函数调用时使用括号,但是,函数的返回类型是必须的。因为函数调用是表达式的一部分。Return语句Return语句用来控制将一个数值返回调用环境。其语法如下:Return
expession;Expession为要返回的值,如果没有相应的类型,那么
expression的取值将被转换为在函数定义的return子句指定的类型。在一个函数中可以有多个return语句,尽管只有一个return语句被执行。函数没有使用return语句结束是错误的。例:Create
or
replace
function
classinfo(p_department
classes.department%type,p_course
classes.course%type)Return
varchar2
isv_currentstudent
number;v_maxstudents
number;v_percentfull
number;Beginselect
current_students,max_studentsinto
v_currentstudents,v_maxstudentsfrom
classeswhere
department=p_departmentand
course=p_course;V_percentfull:=v_currentstudents/v_maxstudents*100;If
v_percentfull=100thenreturn
‘full’;Elsif
v_percentfull>80
thenreturn
‘some
room’;Elsif
v_percentfull>60
thenreturn
‘more
room’;Elsif
v_percentfull>0
thenreturn
‘lots
of
rooms’;Elsereturn
‘empty’;End
if;End
classinfo;Return语句也可以用在过程中,它不需要参数,这将使控制立即传递给调用环境。被为out或inout的形参值被传递给实参,程序从调用过程语句的下一个语句开始执行。函数样式函数与过程共
些相同的特性函数可以通过out参数返回多个数值函数代码拥有
、执行和错误处理部分函数可以接受缺省值函数可以通过位置标识法或带名标识法进行调用如果有多于一个的返回值,那么使用过程,如果仅有一个返回值,那么可以使用函数。尽管函数可以使用out参数返回多个值,但是这种风格不好。在子程序中进行异常处理如果在子程序中发生了错误就要触发一个异常情态(exception).这种异常处理可能是用户定义的或是预定义的。如果过程对于此错误没有异常处理,那么控制
会立即从该过程传递给调用环境,这遵循异常处理传
递规则。但是,在这种情况下,out
和in
out的形参没
有传递给实参。实参将拥有其在调用该过程以前的值。例:Create
or
replace
procedure
raiseerror(p_raise
in
boolean:=true;p_parametera
out
number)
asBeginp_parametera:=7;if
p_raise
thenraise
dup_val_on_index;Elsereturn;End
if;Endraiseerror;如果 从下面的块中调用raiseerrorDeclarev_tempvarnumber:=1;Begindbms_output.put_line(‘initial
value:’||
v_tempvar);raiseerror(false,v_tempvar);Dbms_output.put_line(‘value
after
successful
call:’||
v_tempvar);V_tempvar:=2;Dbms_output.put_line(‘value
before
2nd
call:’||
v_tempvar);Raiseerror(true,v_tempvar);Exceptionwhen
others
thendbms_output.put_line(‘value
afterunsuccessfulecall||v_tempvar);End;在对raiseerror的第一次调用以前,v_tempvar取值为1,第一次调用成功,v_tempvar被赋值7。然后在第二次对raiseerror调用前v_tampvar被赋值为2,第二次调用没有成功,v_tempvar
的值仍然为2。删除过程和函数删除过程和函数意味着过程和函数从数据字典中删除。删除过程的语法如下:Drop
procedure
过程名删除函数的语法如下:Drop
function
函数名例:drop
procedure
addnewstudentsDrop是一个DDL语句,因此在执行该语句的前后都会隐含地执行commit命令。7.3
子程序位置部分子程序可以被
在数据字典中,也可以在块的进行定义,此时该子程序被称作本地子程序。7.3.1内置子程序当通过create
or
replace
命令创建的子程序被
在数据库中,该子程序是以编译的形式进行 的,这就是p_code。P_code对程序的所有 都进行求值,这样,子程序就被转换为被PL/SQL引擎很容易阅读的形式。User_object视图包括了所有对象的信息,其中也包括内置子程序的信息。该信息包括对象创建的时间和最后修改的时间、对象的类型(表、序列、函数等)、以及对象的有效性。User_source视图包含了对象的源代码。
User_errors视图包含了编译器错误的信息。无效的子程序仍然
在数据库中。但是,在消除错误以前,它是不能被执行的。部分
的本地7.3.2本地子程序下面的例子说明了在PL/SQL块的子程序Declarecursor
c_allstudent
isselect
_name,last_name
from
students;v_formattedname
varchar2(50);function
fornatname(p_ name
in
varchar2
,p_lastnamein
varchar2)Return
varchar2
isBeginreturn
p_ _name
||
‘
‘
||
p_lastname;End
formatname;Beginfor
v_studentrecord
in
c_allstudents
loopv_formattedname:=formatname(v_studentrecord.
_name,v_studentrecord.last_name);insert
into
temp_table(char_col)values
(v_formattedname);end
loop;commit;End;Formatname仅在所 的块内可见。他的作用域为从的位置开始到块的结束。其他的块不能调用formatname,因为他对于其他块是不可见的。所有本地子程序都在
部分的尾部进行
。如果将formatname移到c_allstudent
的前面,将得到编译错误。Declarefunction
fornatname(p_ name
in
varchar2
,p_lastname
in
varchar2)Return
varchar2
isBeginreturn
p_ _name
||
‘
‘
||
p_lastname;End
formatname;cursor
c_allstudent
isselect
_name,last_name
from
students;v_formattedname
varchar2(50);Beginfor
v_studentrecord
in
c_allstudents
loopv_formattedname:=formatname(v_studentrecord.
_name,v_studentrecord.last_name);insert
into
temp_table(char_col)values
(v_formattedname);end
loop;commit;End;1.向前因为本地子程序的名字是一个标识符,所以应该在被之前进行
,但是对于相互交叉
的子程序,会出现问题。如:Declarev_tempval
binary_integer
:=5;procedure
a(p_counter
inout
binary_integer)
isbeginif
p_counter>0
thenb(p_counter);p_counter:=p_cpunter-1;end
if;end
a;procedure
b(p_counter
in
out
binary_integer)
isbeginp_counter:=p_counter-1;a(p_counter);end
b;Beginb(v_tempval);End;这个例子是不可能通过编译的。为了解决这个问题,可以使用向前
。这只是一个过程名和形参,这样在程序过程了。中就可以使用相互的交叉例:Declarev_tempval
binary_integer
:=5;procedure
b(p_counter
in
out
binary_integer);procedure
a(p_counter
in
out
binary_integer)isbeginif
p_counter>0
thenb(p_counter);p_counter:=p_counter-1;end
if;end
a;procedure
b(p_counter
in
out
binary_integer)isbeginp_counter:=p_counter-1;a(p_counter);end
b;Beginb(v_tempval);End;内置子程序和本地子程序内置子程序和本地子程序的行为不同,拥有不同的属性。我通常喜欢用内置子程序,他可以在数据库中,被多个块调用。子程序的大小和复杂性方面的收益也是应该考虑因素。我唯一要在某个块内将其为本地子程序的过程和函数是那些比较短小的,并且是那些从程序的特定部分才能进行调用的子程序。(即只能在所在块才能调用的子程序)。内置子程序和本地子程序的差异内置子程序本地子程序在数据库中以被编译的p_code形式 ,在调用该子程序时,不需要再编译作为包含他的块的一部分进行编译,如果该块被多次调用,则该子程序被多次编译。可以从有对该子程序拥有
execute权限的用户所提交的任何块中进行调用。仅能从包含该子程序的块中进行调用。通过将子程序和调用块分离开来,使得调用块更短小和易于理解。如果需要的话,调用块和子程序可以分别进行。该子程序和调用块是同一个,易引起误解,如果要对调用块进行修改,该子程序要重新进行编译。被编译的p_code可以通过使用DBMS_SHARED_POOL.KEEP包装过程嵌入到共享池中。这可以提高性能。本地子程序自己不能嵌插到共享池中。2.子程序依赖性在编译过程或函数的时候,他 的所有oracle对象都被记录到数据字典中。该过程是依赖于这些对象。如果在其中一个对象上执行了DDL操作,内置子程序也可能成为无效的。例:almostfull函数对表classes进行查询。allmostfull仅依赖于一个对象classes。现在假设
创建了一个调用allmostfull并将结果
到temp_table中的过程。Create
or
replace
procedure
recordfullclasses
ascursor
c_classes
isselect
department,coursefrom
classes;Beginfor
v_classesrecord
in
c_classes
loopif
almostfull(v_classesrecord.department,v_classesrecord.course)
theninsert
intotemp_table(char_col)
valuesv_classesrecord.department ||
‘
‘
||v_classesrecord.course
||‘is
almost
full’);end
if;end
loop;End
recordfullclasses;Recordfullclasses直接依赖于almostfull和temp_table,因此recordfullclasses间接依赖于classes。如果在classes表上执行DDL操作,则依赖于classes的所有对象都将是无效的。例
通过修改下面的列将使recordfullclasses和almostfull无效。Alter
table
classes add(student_rating
number(2));对于函数请使用:Alter
function
function_name
compile权限和内置子程序Execute权限要使用内置子程序和包,应有execute的权限。Create
or
replace
procedure
recordfullclasses
ascursor
c_classesisselect
department,coursefrom
classes;Beginfor
v_classesrecord
in
c_classes
loopif
almostfull(v_classesrecord.department,v_classesrecord.course)
theninsert
into
temp_table(char_col)
valuesv_classesrecord.department ||
‘
‘
||v_classesrecord.course
||
‘is
almost
full’);end
if;end
loop;End
recordfullclasses;假设recordfullclasses所依赖的对象almostfull和表classes以及表temp_table都由用户usera所拥有。
recordfullclasses也是由用户usera所拥有。如果
用以下 令授予用户b对recordfullclasses的execute权限:Grant
execute
on
recordfullclasses
to
userb;那么userb可以通过以下的块来执行recordfullclasses。Beginusera.
Recordfullclasses;End;现在假设useb也有temp_table表,useb调用usera.Recordfullclasses,那么哪一个表会被改变呢?答案是usea中的表。原因如下:子程序在其拥有者权限控制下执行既然userb调用Recordfullclasses,而Recordfullclasses由usera所拥有,这样标识符temp_table应该对属于usera,而不是userb的表进行求值。内置子程序和角色假设usea不拥有Recordfullclasses或temp_table,但是useb拥有他。然后修改了Recordfullclasses,将他显式地索引到usea中的对象。Create
or
replace
procedure
Recordfullclasses
ascursor
c_classses
is
select
department,coursefrom
usea.classes;Beginfor
v_classrecord
in
c_classes
loopif
usera.almostfull(v_classrecord.department,v_classrecord.course)
theninsert
intotemp_table(char_col)
values(v_classrecord.department||
‘
‘||
v_classrecord.course
||‘is
almost
full’);End
if;End
loop;End
Recordfullclasses;为了能使Recordfullclasses正确编译,usera必须将关于classes的select权限和关于almostfull的execute权限赋予userb。而且,这种
必须显式地进行,不能通过角色进行。下面由usea所执行的 将使得useb.Recordfullclasses编译成功。Grant
select
on
classes
to
useb;Grant
execute
on
Recordfullclasses
to
useb;通过间接的
,比如:Create
role
usera_role;Grant
select
on
classes
to
usera_role;Grant
execute
on
Recordfullclasses
to
usera_role;Grant
usera_role
to
userb;将不能工作。所以:子程序在其拥有者的控制下执行,这些权限要显式地授予相应的拥有者,
无法通过角色进行。这条法则也适用于包和触发器。7.4
递归在使用递归的时候要
递归的位置。如果将递归调用放在一个游标的FOR循环中或者是游标的open和close之间,则在每次调用的时候都会打开一个游标,这样的结果可能会造成游标数超过oracle初始化参数open_cursor指定的最大值。例:Create
or
replace
function
rec_test(n
integer)return
integer
isBeginif
n=1
thenreturn
1;elsereturn
n*rec_test(n-1);end
if;End
rec_test;调用函数rec_testDeclareI
integer;BeginI:=rec_test(7);Dbms_output.put_line(I);End;TRIGGERSDatabase
triggers
can
be
used
to
perform
any
of
the
following:Audit
data
modificationLog
events
transparentlyEnforce
complex
business
rulesDerive
column
values
automaticallyImplement
complex
security
authorizationsMaintain
replicate
tablesTRIGGERSYou
can
associate
up
to
12
database
triggers
with
a
given
table.
A
database
trigger
has
three
parts:
atriggering
event,an
optional
triggerconstraint,and
a
triggeraction.When
an
event
occurs,
a
database
trigger
is
fired,and
an
predefinedPL/SQL
block
will
perform
thenecessary
action.TRIGGERSSYNTAX:CREATE
[OR
REPLACE]
TRIGGER
trigger_name{BEFORE|AFTER}
triggering_event
ON
table_name[FOR
EACH
ROW][WHEN
condition]DECLAREDeclaration
statementsBEGINExecutable
statementsEXCEPTIONException-handling
statementsEND;Bordoloi
andBockTRIGGERSThe
trigger_name
references
the
name
of
the
trigger.BEFORE
or
AFTER
specify
when
the
trigger
is
fired
(before
orafter
the
triggering
event).The
triggering_event
references
a
DML
statement
issued
againstthe
table
(e.g.,
INSERT,
DELETE,
UPDATE).The
table_name
is
the
name
of
the
table
associated
with
the
trigger.The
clause,
FOR
EACH
ROW,
specifies
a
trigger
is
a
rowtriggerand
firesonce
for
ea odified
row.A
WHEN
clause
specifies
the
condition
for
a
trigger
to
be
fired.Bear
inmind
that
if
you
drop
a
table,
all
the
associated
triggers
forthe
table
are
dropped
as
well.TYPES
OF
TRIGGERSTriggers
may
be
called
BEFORE
or
AFTER
the
followingevents:INSERT,
UPDATE
and
DELETE.The
before/after
options
can
be
used
to
specify
when
thetrigger
body
should
be
fired
with
respect
to
the
triggeringstatement.
If
the
user
indicates
a
BEFORE
option,
thenOracle
fires
the
trigger
before
executing
the
triggeringstatement.
On
the
other
hand,
if
an
AFTER
is
used,Oracle
fires
the
trigger
after
executing
the
triggeringstatement.TYPES
OF
TRIGGERSA
trigger
may
be
a
ROW
or
STATEMENT
type.
If
thestatement
FOR
EACH
ROW
is
present
in
the
CREATETRIGGER
clause
of
a
trigger,
the
trigger
is
a
row
trigger.A
row
trigger
is
fired
for
each
row
affected
byantriggering
statement.
A
statement
trigger,
however,
is
fired
only
once
for
thetriggering
statement,
regardless
of
the
number
of
rowsaffected
by
the
triggering
statementTYPES
OF
TRIGGERSExample:
statement
triggerCREATE
OR
REPLACE
TRIGGER
mytrig1
BEFORE
DELETE
OR
INSERTOR
UPDATE
ON
employeeBEGINIF
(TO_CHAR(SYSDATE,
'day')
IN
('sat',
'sun'))
OR(TO_CHAR(SYSDATE,'hh:mi')
NOT
BETWEEN
'08:30'
AND
'18:30')RAISE_APPLICATION_ERROR(-20500,
'table
is
secured');THENEND
IF;END;/The
above
example
shows
a
trigger
that
limits
the
DMLactions
to
the
employee
table
to
weekdays
from
8.30am
to6.30pm.
If
a
user
tries
toinsert/update/delete
a
row
in
theEBoMrdPoLloOi
aYnEd
E
table,
a
warning
message
will
be
prompted.BockBordoloi
a
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 9 心中的“110”(教学实录)-2024-2025学年道德与法治三年级上册统编版
- 2024年版权许可与技术秘密共享合同
- 2025年保密知识试题库带答案(考试直接用)
- 2024年度文化创意产业债权债务转让与版权保护协议2篇
- 2024年度水电能源供应与需求租赁合同2篇
- 2024年版服装批发市场联营协议
- 四川省凉山州2024-2025学年高一数学上学期第一次月考试题含解析
- 国开大学2024秋《国家开放大学学习指南》在线形考(任务一至五)试题及答案
- 2024体育场租赁合同包括赛事交通引导与停车服务3篇
- 2024年房产转租协议范本版B版
- 变更索赔成功案例-某工程窝工变更索赔报告
- GB 19517-2004国家电气设备安全技术规范
- 模具定期保养点检表
- 山西省太原市市药品零售药店企业药房名单目录
- 工程部长桥梁工程施工技术(PPT116)
- 全面设备保养TPM培训教材课件
- 茶叶企业营销课件
- 高炉无料钟炉顶设备安装与调试技术
- 初中语文人教九年级上册如何分析环境描写的作用 教案
- 压力容器壁厚快速计算
- 抗菌药物供应目录备案表
评论
0/150
提交评论