PL/SQL变量和类型
变量
在定义变量时一定要为其指定一个类型,类型可以是PL/SQL类型或SQL语言的类型,一旦变量的类型确定,那么变量中所能存储的值也就确定了,因此尽管变量的值会经常改变,但是值的类型是不可以变化的。
1.变量的声明
语法:variable_name[CONSTANT] type [NOT NULL] [:=value];
variable_name:用于定义变量名,变量名的命名要符合标识符命名规范。
type:变量需要使用的数据类型,可以使用所有SQL类型或PL/SQL类型。
用方括号 [] 括起来的是可选部分。
CONSTANT:表示声明为一个常量,常量在定义时需要指定初始值,一旦定义其值,不能再被改变。
NOT NULL:用于约束变量的值不能为空。
:=value :用于为变量赋初始值。
代码1.1 变量定义示例
DECLARE
v_empname VARCHAR2(20); --定义员工名称变量
v_deptname VARCHAR2(20); --定义部门名称变量
v_hiredate DATE NOT NULL := SYSDATE; --定义入职日期变量
v_empno INT NOT NULL DEFAULT 1111; --变量员工编码变量
BEGIN
NULL; --不执行任何代码
END;
/
注: :=和DEFAULT是可以互换使用的,都用来为变量赋初始值。
一旦出现了NOT NULL关键字,后面必须具有赋初始值的语句。
2.变量的赋值
如果变量在声明时没有指定初始值,默认情况下,变量被初始化为NULL值。如果未给变量赋值,就直接使用变量,将会产生意想不到的结果。
根据变量的不同类型,可以为变量直接赋常量值,也可以使用表达式来计算变量的值。
下面的代码根据薪资和加薪比例来计算员工的结果薪资值:
DECLARE
v_salary NUMBER(7,2);
v_rate NUMBER(7,2) :=0.12;
v_base_salary NUMBER(7,2) :=1200;
BEGIN
v_salary := v_base_salary*(1+v_rate); --使用表达式为变量赋值
DBMS_OUTPUT.put_line('员工的薪资值为:'||v_salary);
END;
在为PL/SQL变量赋值时,需要注意变量的类型。下面列出了常用的变量类型的复制方式。
DECLARE
v_string VARCHAR2(200);
v_hire_date DATE;
v_bool BOOLEAN; --PL/SQL布尔类型
BEGIN
v_bool:=True; --为布尔类型赋值
v_hire_date:=to_date('2019-04-28','yyyy-mm-dd'); --使用函数为日期赋值
v_hire_date:=SYSDATE; --使用日期函数赋值
v_hire_date:=date'2019-04-28'; --直接赋静态日期值
v_string:='this is a string';
END;
/
通过数据库查询为变量赋数据库中的值,这是进行PL/SQL编程非常常见的赋值方式,例如要从emp表中查询员工的姓名、员工编号和雇佣日期,可以使用如下PL/SQL代码。
DECLARE
v_empno emp.empno%TYPE; --定义变量
v_ename emp.ename%TYPE;
v_hiredate emp.hiredate%TYPE;
BEGIN
SELECT empno , ename , hiredate
INTO v_empno , v_ename , v_hiredate
FROM emp
WHERE empno = &empno;
--输出变量的内容
DBMS_OUTPUT.put_line('员工编号:' || v_empno);
DBMS_OUTPUT.put_line('员工名称:' || v_ename);
DBMS_OUTPUT.put_line('雇佣日期:' || v_hiredate);
END;
在定义变量类型时,使用了%TYPE来声明与数据库列相同的类型,然后通过SELECT-INTO语句查询数据库并将结果写入变量中,可以看到INTO子句中的变量的顺序要与列的顺序一致。
如果SELECT-INTO查询返回多行数据会触发TOO_MANY_ROWS异常,如果未找到任何行数据,会触发NO_DATA_FOUND异常。
3.使用%TYPE
使用PL/SQL的%TYPE,使得开发人员可以给予已有的变量类型,或者是数据列的类型来指定变量的类型。
DECLARE
v_empno emp.empno%TYPE; --使用%TYPE定义emp表empno列类型的变量
v_empno2 v_empno%TYPE; --定义与v_empno相同的变量
v_salary NUMBER(7,3) NOT NULL:=1350.5; --定义薪水变量
v_othersalary v_salary%TYPE:=1500; --定义与v_salary相同类型的变量
BEGIN
NULL;
END;
/
代码中的v_empno使用%TYPE定义了与emp表中empno列相同的类型,而v_empno2定义了与v_empno相同的类型,因此
当emp表中的empno列的类型发生改变后,变量的类型会自动发生变化,并不需要手动地进行维护。
v_salary是一个具有NOT NULL约束的变量声明,在声明时为这个变量指定了初始值,
v_othersalary使用%TYPE定义了与v_salary相同的类型,因此也具有NOT NULL约束。
在声明时同样为v_othersalary指定了变量的初始值,如果不指定这个初始值,PL/SQL引擎会触发异常。
注意:尽管v_othersalary会因为NOT NULL而触发异常,但是emp表的empno列是不允许为空的,对于数据库列类型,%TYPE只提供类型信息,并不提供NOT NULL约束信息,因此即便没有为v_empno或v_empno2指定初始值,也能够正常运行。
通过%TYPE的类型映射功能,使得在类型发生改变时非常容易对代码进行维护,这是一种非常好的编码风格,特别是在操作数据库时,使用%TYPE会使得PL/SQL更加灵活。
4.使用%ROWTYPE
%ROWTYPE是与%TYPE相似的用于绑定到数据库表列的类型,%TYPE仅绑定到单个数据库列的类型,而%ROWTYPE则绑定到一整行的所有列类型,可以将使用%ROWTYPE定义的变量看作是一条数据类型,使用%ROWTYPE的示例代码如下:
DECLARE
v_emp emp%ROWTYPE --定义emp表的所有列类型
BEGIN --查询emo表并将结果写入v_emp记录中
SELECT *
INTO v_emp
FROM emp
WHERE empno = &empno;
--输出结果信息
DBMS_OUTPUT.put_line(v_emp.empno || CHR(10) || v_emo.ename);
END;
代码使用SELECT-INFO直接将一整列的数据插入使用%ROWTYPE定义的记录类型,然后使用DBMS_OUTPUT.put_line输出了最终的结果。
在PL/SQL中,CHR(13)表示回车,CHR(10)表示换行,通常使用CHR(13)||CHR(10)来进行回车换行。
使用%ROWTYPE定义了整行的记录类型后,可以直接使用赋值语法为变量赋值,然后直接使用记录类型字段值插入数据库表。
DECLARE
v_emp emp%ROWTYPE; --定义emp表列类型的记录
BEGIN --为记录类型赋值
v_emp.empno:=8000;
v_emp.ename:='张三丰';
v_emp.job:='掌门';
v_empmgr:=7902;
v_emp.hiredate:=date'2019-04-28';
v_emp.sal:=8000;
v_emp.deptno:=20;
INSERT INTO emp VALUES v_emo; --将记录类型插入数据表
END;
/
上面的代码在使用%ROWTYPE定义了变量之后使用赋值语法为记录中的每个列进行了赋值,最后使用INSERT INTO 语句直接将记录类型插入emp数据表中。
注意:%ROWTYPE与%TYPE一样,只提供类型信息,并不能保证NOT NULL约束。
除了使用%ROWTYPE定义表列类型的变量外,还可以用来定义游标类型的变量,使用%ROWTYPE指定游标类型的变量,变量的值将是游标的SELECT语句查询出来的值,。
下面代码定义了游标emp_cursor,使用%ROWTYPE指定emp_cursor类型的变量。
DECLARE
CURSOR emp_cursor --定义游标类型
IS
SELECT empno , ename , job , sal , hiredate
FROM emp;
--使用%ROWTYPE定义了游标类型的变量
v_emp emp_cursor%ROWTYPE;
BEGIN
OPEN emp_cursor;
--循环并提取游标数据
LOOP
FETCH emp_cursor
INTO v_emp;
--要注意游标移动到最尾部退出游标
EXIT WHEN emp_cursor%NOTFOUND;
--输出游标数据
DBMS_OUTPUT.put_line( v_emp.empno
||''
||v_emp.ename
||''
||v_emp.job
||''
||v_emp.sal
||''
||TO_CHAR(v_emp.hiredate,'YYYY-MM-DD')
);
END LOOP;
--关闭游标
CLOSE emp_cursor;
END;
/
代码定义了游标emo_cursor,然后定义了该游标类型的v_emp变量,使用%ROWTYPE指定类型为游标返回类型,通过提取游标的FETCH-INTO语句,一次将一行数据写入v_emp变量中,然后使用DBMS_OUTPUT.put_line来输出结果值。
参考Oracle PL/SQL从入门到精通 清华大学出版社 作者:丁士锋
PL/SQL变量和类型的更多相关文章
- PL/SQL变量的作用域和可见性
变量的作用域和可见性设计变量在块中的位置,不同的位置使得变量具有不同的有效性与可访问性. 变量的作用域是指可以使用变量的程序单元部分,可以是包和子程序包等. 当一个变量在它的作用域中可以用一个不限定的 ...
- Oracle的pl/sql变量类型
pl/sql定义 sql是结构化查询语言.sql是不是一个编程语言?编程语言一般都能够声明变量,写条件判断,循环.sql不具备这些特征,所有sql不是一门编程语言.我们在实际的开发中,有这种需要,把s ...
- pl sql 变量的声明和赋值
链接地址:http://www.cnblogs.com/zhengcheng/p/4168670.html 一.什么是PL-SQL PL-SQL是结合了Oracle过程语言和结构化查询语言(SQL)的 ...
- 二十四、oracle pl/sql 变量
一.变量介绍在编写pl/sql程序时,可以定义变量和常量:在pl/sql程序中包括有:1).标量类型(scalar)2).复合类型(composite) --用于操作单条记录3).参照类型(refer ...
- oracle pl/sql 变量
一.变量介绍在编写pl/sql程序时,可以定义变量和常量:在pl/sql程序中包括有:1).标量类型(scalar)2).复合类型(composite) --用于操作单条记录3).参照类型(refer ...
- PL/SQL 用户自定义子类型
子类型具有与其基本类型相同的操作,但只有基本类型有效值的子集. 例如,PL/SQL预先定义子类型CHARACTER和INTEGER,如下所示: SUBTYPE CHARACTER IS CHAR; S ...
- PL/SQL 日期时间类型函数及运算
内部存储格式: 世纪.年.月.日.小时.分钟.秒 默认格式是:DD-MON-RR. SYSDATE 返回当前的系统时间. SELECT SYSDATE FROM DUAL: 对日期的数学运算 SELE ...
- PL/SQL之--变量
一.PL/SQL 简介 PL/SQL也是一种程序语言,叫做过程化SQL语言(Procedural Language/SQL).PL/SQL是oracle对sql语句的一种扩展,在普通SQL语句的使用上 ...
- Oracle PL/SQL编程之变量
注: 以下测试案例所用的表均来自与scott方案,使用前,请确保该用户解锁. 1.简介 和大多数编程语言一样,在编写PL/SQL程序时,可以定义常量和变量,在pl/sql程序中包括有: a.标量类型( ...
随机推荐
- DjangoRestFramework学习三之认证组件、权限组件、频率组件、url注册器、响应器、分页组件
DjangoRestFramework学习三之认证组件.权限组件.频率组件.url注册器.响应器.分页组件 本节目录 一 认证组件 二 权限组件 三 频率组件 四 URL注册器 五 响应器 六 分 ...
- request之LIstener监听器
要实现监听request内置对象,必须实现一个接口javax.servlet.ServletRequsetListener. 代码如下: package cn.wangkai.listener; im ...
- C++———库函数cstring及string方法解读
1.string与cstring区别 <string>是C++标准库头文件.包含了拟容器class std::string的声明(不过class string事实上只是basic_stri ...
- js 高阶函数 闭包
摘自 https://www.cnblogs.com/bobodeboke/p/5594647.html 建议结合另外一篇关于闭包的文章一起阅读:http://www.cnblogs.com/bob ...
- PHP 利用CURL(HTTP)实现服务器上传文件至另一服务器
// 上传端 /** * 向目标地址推送xls文件 * @Date 2019/4/29 */ public function putXls() { // 目标接口 $url = "http: ...
- mysql.user表详解
GRANT语法: GRANT 权限 ON 数据库.* TO 用户名@'登录主机' IDENTIFIED BY '密码' 权限: ALL,ALTER,CREATE,DROP,SELECT,U ...
- java.lang.IllegalStateException: Connection pool shut down
最近使用HttpClient 4.5 使用 CloseableHttpClient 发起连接后,使用CloseableHttpResponse 接受返回结果,结果就报错了,上网查了下,有位stacko ...
- Java面向对象——类,对象和方法
1.类的概念 在生活中,说到类,可以联想到类别,同类,会想到一类人,一类事物等等.而这一类人或事物都是具有相同特征或特点和行为的,我们根据不同的特征或特点和行为将他们归类或分类.同时,当我们认识一个新 ...
- hybrid简单了解
技术点总有它的来由. 文章概要: 1.hybrid 基本概念 2.前端和客户端的交互 3.前端和客户端的交互实现 4.前端交互实现关注点 5.小结 1.hybrid 基本概念 ⑴.什么是hybrid? ...
- 测试客户端连接12c ASM实例
环境:Oracle 12.2.0.1 RAC 背景:用户反映12c ASM创建的用户具备sysasm权限,但无法在客户端连接到ASM实例,且没有报错. 1.ASM实例创建用户赋予sysasm权限 2. ...