zoukankan      html  css  js  c++  java
  • 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从入门到精通 清华大学出版社 作者:丁士锋

  • 相关阅读:
    ORACLE 循环
    C#生成指定数目的互不相同的随机数(转)
    Oracle自治事务的介绍
    螺旋矩阵--我的实现方法
    一个体育生的编程之路(一)
    判断十二星座——我的算法,大家看是不是比较简便
    简单的排序算法——插入排序,选择排序,交换排序(冒泡排序,快速排序)
    使用VC和DirectShow从摄像头中读取图像(一)
    1999那个追着打我的女生
    我自己写的几个C++常用方法
  • 原文地址:https://www.cnblogs.com/harriets-zhang/p/10783609.html
Copyright © 2011-2022 走看看