变量

  在定义变量时一定要为其指定一个类型,类型可以是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变量和类型的更多相关文章

  1. PL/SQL变量的作用域和可见性

    变量的作用域和可见性设计变量在块中的位置,不同的位置使得变量具有不同的有效性与可访问性. 变量的作用域是指可以使用变量的程序单元部分,可以是包和子程序包等. 当一个变量在它的作用域中可以用一个不限定的 ...

  2. Oracle的pl/sql变量类型

    pl/sql定义 sql是结构化查询语言.sql是不是一个编程语言?编程语言一般都能够声明变量,写条件判断,循环.sql不具备这些特征,所有sql不是一门编程语言.我们在实际的开发中,有这种需要,把s ...

  3. pl sql 变量的声明和赋值

    链接地址:http://www.cnblogs.com/zhengcheng/p/4168670.html 一.什么是PL-SQL PL-SQL是结合了Oracle过程语言和结构化查询语言(SQL)的 ...

  4. 二十四、oracle pl/sql 变量

    一.变量介绍在编写pl/sql程序时,可以定义变量和常量:在pl/sql程序中包括有:1).标量类型(scalar)2).复合类型(composite) --用于操作单条记录3).参照类型(refer ...

  5. oracle pl/sql 变量

    一.变量介绍在编写pl/sql程序时,可以定义变量和常量:在pl/sql程序中包括有:1).标量类型(scalar)2).复合类型(composite) --用于操作单条记录3).参照类型(refer ...

  6. PL/SQL 用户自定义子类型

    子类型具有与其基本类型相同的操作,但只有基本类型有效值的子集. 例如,PL/SQL预先定义子类型CHARACTER和INTEGER,如下所示: SUBTYPE CHARACTER IS CHAR; S ...

  7. PL/SQL 日期时间类型函数及运算

    内部存储格式: 世纪.年.月.日.小时.分钟.秒 默认格式是:DD-MON-RR. SYSDATE 返回当前的系统时间. SELECT SYSDATE FROM DUAL: 对日期的数学运算 SELE ...

  8. PL/SQL之--变量

    一.PL/SQL 简介 PL/SQL也是一种程序语言,叫做过程化SQL语言(Procedural Language/SQL).PL/SQL是oracle对sql语句的一种扩展,在普通SQL语句的使用上 ...

  9. Oracle PL/SQL编程之变量

    注: 以下测试案例所用的表均来自与scott方案,使用前,请确保该用户解锁. 1.简介 和大多数编程语言一样,在编写PL/SQL程序时,可以定义常量和变量,在pl/sql程序中包括有: a.标量类型( ...

随机推荐

  1. Python全栈-magedu-2018-笔记1

    第一章 - Python 环境搭建 操作系统准备 准备Linux最小系统即可. 如果在虚拟机中克隆,MAC地址会变. 这里使用CentOS 6.5+ Pyenv 安装 安装git yum instal ...

  2. WPF气泡样式弹窗效果

    页面设计需求,做了一个气泡形状的弹出框,效果如下: 设计思路如下: 1. 使用Path绘制气泡的尖尖,将这个放到顶层: 2. 在用border绘制长方形框,将这个放到底层,并且设置Margin值,使得 ...

  3. kubernetes in action - Services

    问题,如何将Pod所提供的功能提供给别人用?微服务,是服务,所以关键要把服务提供出去 直接把pod的静态ip提供给用户用,这个会有很多问题,比如failover,扩容,负载均衡等 所以需要servic ...

  4. STA 463 Simple Linear Regression Report

    STA 463 Simple Linear Regression ReportSpring 2019 The goal of this part of the project is to perfor ...

  5. 2019-oo-第二单元总结

    2019-OO-第二单元总结 多线程电梯调度问题 思路综述 第一次作业 第一次作业是非常简单的傻瓜电梯,不需要考虑容量,不需要考虑调度策略,运用了基本的生产者消费者模型,而且生产者消费者模型也一直贯穿 ...

  6. ES6语法 Promise Iterator

    类和对象 基本定义: class Parent{ constructor(name='lmx'){ //name= 默认值 this.name=name } } let v_parent = new ...

  7. react-devtool 消息处理渲染 源码理解

    react-devtools 有chrome插件版,但在chrome 插件下的通信调试不够透明,且chrome 的插件特别是开发工具界面几乎无法调试. 看到了react-devtools 也提供ele ...

  8. 5.6版本GTID复制异常处理一例(转)

    http://imysql.com/2014/07/31/mysql-faq-exception-replication-with-gtid.shtml 昨天处理了一个MySQL 5.6版本下开启GT ...

  9. sql相同表不同查询条件合并显示

    关键字:FULL JOIN 只要其中某个表存在匹配,FULL JOIN 关键字就会返回行. select a.createtime, ISNULL(lp, 0) lp , ISNULL(hp, 0) ...

  10. mysql语句,插入id随机生成

    insert into 表名 VALUES(uuid(),…) 还有一个uuid_short(),只有数字 insert into 表名 VALUES(uuid_short(),…)