oracle绝密培训 3plsql基础.docx
- 文档编号:11744655
- 上传时间:2023-03-31
- 格式:DOCX
- 页数:47
- 大小:69.42KB
oracle绝密培训 3plsql基础.docx
《oracle绝密培训 3plsql基础.docx》由会员分享,可在线阅读,更多相关《oracle绝密培训 3plsql基础.docx(47页珍藏版)》请在冰豆网上搜索。
oracle绝密培训3plsql基础
第三章:
plsql基础
学习目标
⏹能运用PL/SQL语句编写简单的程序
⏹熟练使用控制结构语句
⏹知道游标、过程函数、触发器的作用
⏹能够定义过程游标和建立触发器
⏹通过上机熟练掌握PL/SQL
⏹
PL/SQL概述
PL/SQL的全称是:
ProcedurealLanguage/SQL即过程化SQL语言。
它是在标准SQL语言下发展起来的,PL/SQL语言将变量、控制结构、过程和函数等结构化程序设计的要素引入到SQL语言中。
它的特点是:
具有模块化的结构、使用过程化语言控制结构、能够进行错误处理。
Pl/sql是一个块结构,划分为:
声明部分(declarativesection)
执行部分(executablesection)
异常处理部分(exceptionsection)
其格式如下:
Declare
声明部分
Begin
执行部分
Exception
异常执行部分
End;
Pl/sql块中的注释分为:
●单行注释(--)
●多行注释(/**/)
●
Pl/sql块的标识符由一个字母开始,后面选折性地跟随任意多的字母,数字,货币符号($),下划线(_),#等符号组成.不允许使用空格,斜线(/),短横线(-),&,%.最大长度为30个字符.
Pl/sql块的字符集由如下字符组成:
大写字母A-Z和小写字母a-b
数字0-9
符号
(,),+,-,*,/,<,>,=,!
~,^,;,:
.,’,@,”,#,$,_,|,{,},?
[,]
制表符,空格符,回车符等非显示的间空符号.
其中一些字符用于编程,另外一些用做算术运算符或关系运算符
⏹声明及变量
Pl/sql块的变量声明块由DECLARE关键字开始,BEGIN程序体结束。
是一种强类型语言,如:
Declare
v_idinteger;
v_namevarchar(20);
begin
其变量的定义语法如下:
Varriable_name[CONSTANT]databyte
[NOTNULL][:
=|DEFAULTexpression]
如果有了NOTNULL约束条件,则初始化必须赋值。
也可以直接赋值(使用语法:
=),也可以通过SQLSELECTINTO或FETCHINTO给变量赋值。
⏹表达式
Pl/sql块中也可以执行各种算术表达式,如下:
declare
resultnumber;
begin
result:
=10+3*4+40;
dbms_output.put_line('result:
'||result);
end;
执行结果为:
Result:
62
PL/SQL过程已成功完成。
Dbms_output.put_line函数是输出后换行,put是输出不换行.
⏹PL/SQL运行环境
Pl/sql块可以运行在如下的环境中:
1.SQL*PLUS:
oracle经典客户端连接工具。
2.TOAD:
第三方公司的客户端连接工具。
3.PL/SQLDeveloper:
第三方公司的客户端连接工具。
⏹PL/SQL程序块示例
下面我们来看两个例子:
例1:
--将date数据类型隐式转换为timestamp并输出
declare
v_checkouttimestamp(6);
begin
v_checkout:
=sysdate;
dbms_output.put_line(v_checkout);
end;
例2:
--将当前时间增加1年零3个月输出
declare
v_lifetimeintervalyear(4)tomonth;
aadate;
begin
v_lifetime:
=interval'0001-3'yeartomonth;
selectsysdate+v_lifetimeintoaafromdual;
dbms_output.put_line(aa);
end;
⏹PL/SQL数据类型
Pl/sql数据类型由:
建表数据类型+建表兼容类型+Boolean+
%type+
%rowtype+
%record+
Table
组成。
其中boolean不属于建表类型,在数据库中不能直接表示true,false,而用数字或者字符类型代替,下面我们介绍下面四种数据类型,如下:
⏹%type数据类型
我们通过一个例子来说明这个数据类型,如下:
declare
v_enameemp.ename%type;
v_salemp.sal%type;
c_tax_rateconstantnumber(3,2):
=0.03;
v_sal_taxv_sal%type;
begin
selectename,salintov_ename,v_salfromemp
whereempno=&eno;
v_sal_tax:
=v_sal*c_tax_rate;
dbms_output.put_line('雇员名字:
'||v_ename);
dbms_output.put_line('雇员薪水:
'||v_sal);
dbms_output.put_line('雇员所得税:
'||v_sal_tax);
end;
在这个例子中,我们定义v_ename变量的时候没有用到varchar2数据类型,而是直接映射到emp表中的ename字段类型上了,这样当表中的此字段数据类型改变时,v_ename变量数据类型也改变了。
⏹%rowtype
我们通过一个例子来说明这个数据类型,如下:
declare
v_empemp%rowtype;
begin
select*intov_empfromempwhereempno=&eno;
dbms_output.put_line('雇员名字:
'||v_emp.ename);
dbms_output.put_line('雇员薪水:
'||v_emp.sal);
dbms_output.put_line('雇员工种'||v_emp.job);
end;
在这个例子中,我们定义v_emp变量的时候直接映射到emp表中的所有字段类型,形成一个集合,这样当我们取出其中的一个的时候,就可以使用v_emp.”字段名字”就可以了。
⏹record数据类型
这个数据类型类似于结构(structure),属于自定义数据类型的一种,定义的语法如下:
typerecord_typeisrecord(v1data_type1,v2data_type2,vndata_typen);
下面我们看一个例子:
declare
typeemp_record_typeisrecord(
nameemp.ename%type,
salaryemp.sal%type,
jobemp.job%type);
emp_recordemp_record_type;
begin
selectename,sal,jobintoemp_recordfromempwhereempno=&eno;
dbms_output.put_line('雇员名:
'||emp_record.name);
dbms_output.put_line('工资:
'||emp_record.salary);
dbms_output.put_line('岗位:
'||emp_record.job);
end;
在这个例子中,我们定义emp_record变量使用了自定义的recode数据类型emp_record_type,这样我们就可以象结构一样来使用了。
⏹table数据类型
talbe数据类型类似于数组,其定义的语法如下:
typetable_typeistableofdata_typeindexbybinary_integer;
下面我们来看一个table数据类型的例子:
declare
typeemp_table_typeistableofemp.ename%typeindexbybinary_integer;
emp_tableemp_table_type;
begin
selectenameintoemp_table(-1)fromempwhereempno=&eno;
emp_table(0):
='jack';
emp_table
(1):
='lucy';
dbms_output.put_line('emp_table(-1)雇员
名:
'||emp_table(-1));
dbms_output.put_line('emp_table(0):
'||emp_table(0));
dbms_output.put_line('emp_table
(1)'||emp_table
(1));
end;
下面再介绍一个数字类型的数组了,如下:
DECLARE
TYPEarrayISTABLEOFNUMBERINDEXBYBINARY_INTEGER;
firstnumberarray;
secondnumberarray;
BEGIN
firstnumber(0):
='123456';
firstnumber
(1):
='888888';
secondnumber(0):
='222222';
secondnumber
(1):
='666666';
FORiIN0..firstnumber.count-1LOOP
DBMS_OUTPUT.PUT_LINE('i='||i||',
firstnumber[0]='||firstnumber(i)||',
secondnumber='||secondnumber(i));
ENDLOOP;
END;
⏹流程控制
Pl/sql块的流程控制语句也分为以下三种:
●条件控制
●循环控制
●顺序控制
⏹条件控制
其语法如下:
IFcondition1THEN
statements1
ELSIFcondition2THEN
statements2
ELSE
statements3
ENDIF;
下面我们看一个例子:
declare
v_salnumber(7,2);
begin
selectsalintov_salfromempwhereename='SCOTT';
dbms_output.put_line('scottsalary:
'||v_sal);
ifv_sal<100then
dbms_output.put_line('scott工资低于1000');
else
if1000<=v_salandv_sal<2000then
dbms_output.put_line('scott1在1000到2000之间');
else
dbms_output.put_line('scott1工资高于2000');
endif;
endif;
end;
我们完全可以用case语句实现,case语句的语法如下:
CASE结构
CASE
WHEN条件表达式1THEN
语句段1
WHEN条件表达式2THEN
语句段2
……
ELSE
语句段N
ENDCASE;
下面我们改造它:
declare
v_salnumber(7,2);
begin
selectsalintov_salfromempwhereename='SCOTT';
dbms_output.put_line('scott工资:
'||v_sal);
case
whenv_sal<1000then
dbms_output.put_line('scott工资低于1000');
when1000<=v_salandv_sal<2000then
dbms_output.put_line('scott工资在1000到2000之间');
else
dbms_output.put_line('scott工资高于2000');
endcase;
end;
case还可以后面跟一个变量,下面我们来看case的第二种语法,如下:
declare
v_gradechar:
='a';
begin
casev_grade
when'a'then
dbms_output.put_line('excellent');
when'b'then
dbms_output.put_line('verygood');
when'c'then
dbms_output.put_line('good');
else
dbms_output.put_line('nosuchgrade');
endcase;
end;
变量v_grade在a,b,c之中,所以完全可以用
Case变量
Case条件
这样的语法来实现。
⏹循环控制
包括:
1.简单循环:
须显示结束循环
2.while循环:
直到条件不满足时结束循环
3.for循环:
循环预先确定的次数
⏹简单循环
语法如下:
[<<循环标签>>]
LOOP
statement
ENDLOOP[循环标签];
跳出循环:
EXIT[循环标签]
EXIT[循环标签]WHEN条件表达式
我们来看一个例子:
--计算100的整数和
declare
v_inumber:
=1;
v_snumber:
=0;
begin
loop
exitwhenv_i>100;
v_s:
=v_s+v_i;
v_i:
=v_i+1;
endloop;
dbms_output.put_line(v_s);
end;
⏹while循环
其语法如下:
while循环
[<<循环标签>>]
WHILE条件表达式LOOP
语句段
ENDLOOP[循环标签];
我们用此循环实现100的整数和,如下:
declare
v_inumber:
=1;
v_snumber:
=0;
begin
whilev_i<=100loop
v_s:
=v_s+v_i;
v_i:
=v_i+1;
endloop;
dbms_output.put_line(v_s);
end;
⏹for循环
语法结构如下:
FOR循环变量IN[REVERSE]初始表达式..终值表达式LOOP
语句段
ENDLOOP[循环标签];
对于100的整数和,我们再用for循环实现,如下:
declare
v_snumber:
=0;
begin
forv_iin1..100loop
v_s:
=v_s+v_i;
endloop;
dbms_output.put_line(v_s);
end;
⏹循环嵌套
循环可以嵌套,如:
--while嵌套while
WHILE条件1LOOP
语句段11
WHILE条件2LOOP
语句段2
ENDLOOP;
语句段12
ENDLOOP;
--简单循环嵌套while循环
LOOP
语句段11
WHILE条件1LOOP
语句段2
ENDLOOP;
语句段12
EXITWHEN条件2
ENDLOOP;
下面我们来看一个例子:
--计算100-110之间的素数
--对于一个整数m而言,把m分别用2到(m-1)的整数除,如果能被其中任何一个数整除,则表示m不是素数,素数肯定是奇数
declare
v_mnumber:
=101;
v_inumber;
v_nnumber:
=0;
begin
whilev_m<110loop
v_i:
=2;
loop
ifmod(v_m,v_i)=0then
v_i:
=0;
exit;
endif;
v_i:
=v_i+1;
exitwhenv_i>v_m-1;
endloop;
ifv_i>0then
v_n:
=v_n+1;
dbms_output.put_line(v_n||''||v_m);
endif;
v_m:
=v_m+2;
endloop;
end;
还可以与for循环进行嵌套,如:
FOR计数器IN上界…下界LOOP
语句段11
LOOP
语句段2
EXITWHEN条件1
ENDLOOP;
语句段12
ENDLOOP;
下面我们再用for循环来改写它:
--用嵌套for循环改写
declare
labelnumber:
=0;
begin
forv_sin101..110loop
forv_iin2..v_s-1loop
ifmod(v_s,v_i)=0then
label:
=0;
exit;
endif;
label:
=label+1;
endloop;
iflabel>0then
dbms_output.put_line(v_s);
endif;
endloop;
end;
⏹顺序控制
顺序控制包括goto语句和null语句,如下:
Goto语句
语法:
GOTO标签
NULL语句
语法:
NULL;
(表示什么也不执行)
下面我们来看一个例子:
--goto语句的例子
declare
v_inumber:
=0;
v_snumber:
=0;
begin
<
=v_i+1;
ifv_i<=100then
v_s:
=v_s+v_i;
gotolabel_1;
endif;
dbms_output.put_line(v_s);
end;
--null语句的例子
declare
v_empnoemp.empno%type;
v_enameemp.ename%type;
v_salemp.sal%type;
begin
v_empno:
=&emp_no;
selectename,salintov_ename,v_salfromempwhereempno=v_empno;
ifv_sal<=3000then
updateempsetcomm=v_sal*01whereempno=v_empno;
dbms_output.put_line(v_ename||'补助'||v_sal*0.1);
else
null;
endif;
end;
⏹异常处理
获取oracle的异常在异常代码段中,其语法如下:
Exception
when异常错误名称1[or异常错误名称2]then
语句段1
when异常错误名称3[or异常错误名称4]then
语句段2
……
whenothersthen
语句段3
End;
我们来看一个例子:
declare
v_enameemp.ename%type;
begin
selectenameintov_enamefromemp
whereempno=&emp_no;
dbms_output.put_line('雇员名'||v_ename);
exception
whenno_data_foundthen
dbms_output.put_line('雇员号不存在,请重新输入'||v_ename);
end;
注意:
&emp_no是pl/sql中的输入参数,当输入一个数据库中没有的值的时候,则会报出异常,我们在exception段中利用异常no_date_found去捕捉这个异常,并输出用户容易理解的提示信息。
类似no_data_found这类的异常称之为系统预定义异常。
⏹预定义异常
Oracle提供的预定义异常如下表所示:
异常错误名称
错误代码
描述
access_into_null
-6530
当开发对象类型应用时,在引用对象属性之前,必须首先初始化对象。
如果试图给一个没有初始化的对象属性赋值,就会引发该异常错误
cast_not_found
-6592
在CASE语句中没有包含必需的WHen子句,并且没有包含ELSE子句
cursor_alread_open
-6511
试图打开一个已经打开的游标。
一个游标在被重复打开之前必须关闭。
一个游标FOR循环会自动打开所涉及的游标,所以在游标循环中不能打开游标。
dup_val_on_index
-1
向有唯一性索引约束的列插入重复值
invalid_cursor
-1001
试图执行一个无效的游标操作
invalid_number
-1722
将字符串转换为数字时失败。
在过程性语句中,将引发VALUE_ERROR错误
login_denied
-1017
用无效的用户名或口令登录ORACLE
no_data_found
-100
SELECTINTO语句没有返回任何行,或者程序引用一个嵌套表中已经被删除的元素,或索引表中一个没有被初始化的元素
not_logged_on
-01012
在没有登录ORACLE数据的情况下,访问数据库
program_error
-6501
ORACLE内在错误,通常是由PL/SQL本身造成的,这种情况下应该通知ORACLE公司的技术部门
storage_error
-6500
PL/SQL程序在运行时内存不够或者内存有问题
timeout_on_resource
-51
ORACLE在等待资源时发生超时现象
Too_many_rows
-1422
SELECTINTO语句返回多行
value_error
-6502
发生了一个算法、转换、截断或者大小约束错误。
如果在一个SQL语句中发生这些错误,则会引发INVALID_ERROR错误
zero_divide
-1476
发生被0除的错误
我们通过几个例子来熟悉这些异常,如下:
例1:
declare
v_salemp.sal%type;
begin
selectsalintov_salfromempwhereempno=&emp_no;
case
whenv_sal<1000then
updateempsetsal=v_sal+100whereempno=&emp_no;
whenv_sal<2000then
updateempsetsal=v_sal+15
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- oracle绝密培训 3plsql基础 oracle 绝密 培训 plsql 基础