Oracle PL/SQL编程之变量
注:
以下测试案例所用的表均来自与scott方案,使用前,请确保该用户解锁.
1、简介
和大多数编程语言一样,在编写PL/SQL程序时,可以定义常量和变量,在pl/sql程序中包括有:
a、标量类型(Scalar)
b、复合类型(Composite)
c、参照类型(Refrence)
d、lob(large object)类型
下面来一一介绍
2、标量(Scalar)类型 只能存放单个值的变量
在编写pl/sql语句时,如果需要用到变量,那么就需要在定义部分定义变量。pl/sql中定义变量个常量的语法如下:
identifier [constant] datatype [not null] [:=| default expr]
identifier:名称
constant:指定常量,需要指定它的初始值,且其值是不能改变的
datatype:数据类型
not null:指定变量值不能为空
:=给变量或者常量指定初始值
defalut:用于指定初试值
expr:指定初始值的pl/sql表达式,可是文本值、其他变量或者函数
2.1、标量定义的案例
定义一个变长字符串
v_name varchar2(10);
定义一个小数 范围 -9999.99~9999.99
v_sal number(6,2)
定义一个小数,并给定初始值6.6 注: :=是pl/sql的变量赋值号
v_num number(6.2):=6.6
定义一个日期类型的数据
v_date date;
定一个布尔变量,不能为空,初始值为false;
v_bool boolean not null defalut false;
注:pl/sql中使用标量并给其赋初值的方式不同于其他的编程语言,需要在等号前加":"
2.2、标量使用的案例
作用:变量是存放pl/sql块中最普通的变量
输入一个员工号,显示雇员的姓名、工资、个人所得税(税率为0.03),代码如下:
declare
c_tax_rate number(3,2):=0.03;
v_name varchar2(5);
v_sal number(7,2);
v_tax_sal number(7,2);
begin
select ename,sal into v_name,v_sal from emp where empno=&no;
v_tax_sal:=v_sal * c_tax_rate;
dbms_output.put_line('姓名是:'||v_name||'工资:'||v_sal||'交税:'||v_tax_sal);
end;
ok,输出成功!
但是上面的代码存在漏洞
我们给变量指定了定长,但是如果我们输入的编号对应的ename的长度大于5,就像下面这样:
我输入了7654,这时对应的ename的长度大于5,所以程序包错了
所以必须解决这个问题,当我们不知道变量长度的时候,让其长度和对应的表字段匹配,从而使程序不抱错,解决方案参考2.3
2.3、标量中使用%type
declare
c_tax_rate number(3,2):=0.03;
v_name emp.ename%type;
v_sal emp.sal%type;
v_tax_sal emp.sal%type;
begin
select ename,sal into v_name,v_sal from emp where empno=&no;
v_tax_sal:=v_sal * c_tax_rate;
dbms_output.put_line('姓名是:'||v_name||'工资:'||v_sal||'交税:'||v_tax_sal);
end;
ok,再次输入7654,正常输出。
3、复合变量(composite) 用于存放多个值的变量
3.1、复合类型-pl/sql记录
类似高级语言中的结构体,需要注意的是,当引用pl/sql记录中的成员时,必须要加记录变量作为前缀(记录变量.记录成员),如果定义一个pl/sql记录类型呢?代码如下:
declare
type emp_record_type is record(
name emp.ename%type,
salary emp.sal%type
);
这样就定义了一个名为emp_record_type的复杂变量类型,那么如何使用这个类型呢?代码如下:
sp_record emp_record_type;
ok,这样就定义了一个emp_record_type类型的变量,名为sp_record;
declare
type emp_record_type is record(
name emp.ename%type,
salary emp.sal%type
);
sp_record emp_record_type;
begin
select ename,sal into sp_record from emp where empno=7788;
dbms_output.put_line('员工名:'|| sp_record.name||'工资:'||sp_record.salary);
end;
ok,使用复合类型-pl/sql记录成功的输出了员工名和工资
3.2、复合类型-pl/sql表
这种类型相当于高级语言的数组,但需要注意的是高级语言中的数组下标不能为负数,而pl/sql可以是可以为负数,而且表元素的下标没有限制。如何定义一个pl/sql表类型呢?代码如下:
declare
type sp_table_type is table of emp.ename%type index by binary_integer;
ok,上面的代码定义了一个类型为emp.ename的pl/sql表类型,也可以理解为类型为emp.ename的数组,那么如何使用这个类型,代码如下:
sp_table sp_table_type
ok,这样就定义了一个emp_table_type类型的变量,名为sp_table;
declare
type sp_table_type is table of emp.ename%type index by binary_integer;
sp_table sp_table_type;
begin
select ename into sp_table(0) from emp where emp.empno=7788;
dbms_output.put_line('姓名是:'||sp_table(0));
end;
ok,上面的代码将empno为7788的员工姓名放入了sp_table中,并指定其下标为0,所以我们在下面输出时,指定输出sp_table(0),所以正常输出,
下面是使用pl/sql表类型经常出错的地方:
i、但是当我们指定存放的下标为-1,而输出的下标为0时,代码就会报错,具体的代码如下:
declare
type sp_table_type is table of emp.ename%type index by binary_integer;
sp_table sp_table_type;
begin
select ename into sp_table(-1) from emp where emp.empno=7788;
dbms_output.put_line('姓名是:'||sp_table(0));
end;
所以当我们使用pl/sql表类型时,需要注意下标的对应
ii、当查询返回的结果集是多个,但是又指定pl/sql表类型的下标,相当于pl/sql表类型只接受一个值,这个时候会报错,具体代码如下:
declare
type sp_table_type is table of emp.ename%type index by binary_integer;
sp_table sp_table_type;
begin
select ename into sp_table(-1) from emp;
dbms_output.put_line('姓名是:'||sp_table(-1));
end;
select ename from emp,返回了多个结果,而into sp_table(-1)只接受一个值,所以报上面的错误了。
4、参照变量
参照变量是指用于存放数值指针的变量,通过使用参照变量,可以使应用程序共享相同对象,从而降低占用的空间。在编写pl/sql程序时,可以使用游标变量(ref cursor)和对象类型变量
(ref obj_type)两种参照变量类型。
4.1、参照变量-ref cursor游标变量
使用游标时,当定义游标时,不需要指定相应的select 语句,但是当使用游标时,就需要指定select语句,这样一个游标就和一个selec语句结合了.下面是游标的案例
a、请使用pl/sql编写一个块,可以输入部门号,显示该部门下所有员工的姓名和工资,代码如下:
首先定义一个游标类型:
type sp_emp_cursor is ref cursor;
接着定义一个sp_emp_cursor游标类型的游标变量
test_cursor sp_emp_cursor;
然后打开游标,将游标与结果集结合
open test_cursor for select ename,sal from emp where empno=&no;
ok,现在test_cursor指向了select ename,sal from emp where empno=&no 结果集
然后循环游标,取出我们想要的数据,然后赋值给定义好的标量,并输出给标量,循环完毕(游标使用完毕),关闭游标,代码如下:
declare
type sp_emp_cursor is ref cursor;--定义一个游标类型
test_cursor sp_emp_cursor;--定义一个游标变量
v_ename emp.ename%type;
v_sal emp.sal%type;
begin
--执行
--把test_cursor和一个select结合
open test_cursor for select ename,sal from emp where deptno=&no;
--循环取出
loop
fetch test_cursor into v_ename,v_sal;
--判断test_cursor是否循环到空数据,如果循环到空数据,那么就停止循环
exit when test_cursor%notfound;
dbms_output.put_line('姓名:'||v_ename||'工资:'||v_sal);
end loop;
--使用完毕关闭游标
close test_cursor;
end;
ok,完成a需求。
b、在a的基础上,如果某个员工的工资低于200元,就增加100元。使用游标完成需求。
- 分布式监控系统Zabbix-3.0.3--短信报警设置
- linux下用户操作记录审计环境的部署记录
- open-falcon ---客户机agent操作
- 双拼域名yansuan.com被木雨林收购
- open-falcon ---安装Dashboard时候报错"SSLError: The read operation timed out"
- Flash/Flex学习笔记(37):不用系统组件(纯AS3)的视频播放器--只有8.82K
- Flash/Flex学习笔记(35):如何正确监听Stage对象的事件
- Flash/Flex学习笔记(34):AS3中的自定义事件
- 字符串处理总结(旧)
- 计算某年某月的某一天是星期几的算法
- Flash/Flex学习笔记(33):如何用As3协同Flash CS IDE控制MovieClip实例
- live writer的折腾
- 用C语言写的万年历---亲手写的。好累哦
- Flash/Flex学习笔记(32):播放音乐并同步显示lyc歌词(适用于Silverlight)
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- laravel5.6中的外键约束示例
- Yii框架核心组件类实例详解
- Python 绘制可视化折线图
- Laravel (Lumen) 解决JWT-Auth刷新token的问题
- PHP单元测试配置与使用方法详解
- Windows平台PHP+IECapt实现网页批量截图并创建缩略图功能详解
- laravel 查询数据库获取结果实现判断是否为空
- 浅析PHP中的 inet_pton 网络函数
- php解压缩zip和rar压缩包文件的方法
- laradock环境docker-compose操作详解
- laravel中的fillable和guarded属性详解
- PHP的图像处理实例小结【文字水印、图片水印、压缩图像等】
- Laravel 6 将新增为指定队列任务设置中间件的功能
- Python生成器传参数及返回值原理解析
- PHP Swoole异步MySQL客户端实现方法示例