*** 所有的编程语言中变量时使用最频繁的。PL/SQL作为一个面向过程的数据库编程语言同样少不了变量,
利用变量可以把PL/SQL块需要的参数传递进来,做到动态执行程序,同时也可以利用变量在PL/SQL
内部进行值得相互传递,甚至可以把值传递出去,最终返回给用户。由此可见,变量是PL/SQL不可缺
少的一部分。
--- 变量、常量的类型及语法
*** 变量就是它所表示的值是可以变化的,而常量就是当初始化后,其值不可以再改变。PL/SQL 是一种
强类型的语言,所以当使用变量或常量的时候必须声明,否则提示错误。下面是变量和常量的声明的
语法介绍:
(1)、变量声明语法结构
01 variable_name datatype
02 [
03 [NOT NULL]
04 { := | DEFAULT } expression
05 ] ;
【语法说明】
》》 variable_name : 表示变量的名称。名称可以根据读者实际情况自行定义。
》》 datatype : 变量的数据类型
》》 第 2~ 5 行表示可选部分。如果没有这部分,那么只需要变量的名称以及对应的
数据类型即可,声明的时候变量可以不赋值
》》 NOT NULL : 表示非空约束
》》 { := | DEFAULT } : 当使用 NOT NULL 属性时,大括号里的内容为必需,表示二选一;
“ := ” 表示赋值 ; DEFAULT 表示默认值
》》 expression :表示变量存储的值,该项可以是表达式
(2)、常量声明语法结构
01 constant_name CONSTANT datatype
02 [ NOT NULL ]
03 { := | DEFAULT } expression
【语法说明】
》》constant_name :表示声明的常量名称
》》CONSTANT : 如果表示常量,该项必须有,否则表示变量
》》 datatype : 常量的数据类型
》》 NOT NULL : 表示常量值非空
》》{ := | DEFAULT } 表示常量必须显式地为其赋值,方式同变量一样
》》 expression :值或表达式
变量和常量的语法结构相似,其中 expression 表示的含义完全一样,都可以是如下类型的表达式:
》》字符型表达式
》》数值型表达式
》》日期型表达式
》》布尔型表达式
》》直接的一个值
变量和常量的数据类型可以概括地分为如下三种类型:
》》标量类型变量:单一类型,不存在组合
》》符合类型变量:由几种单一类型组合而成的一个结构体
》》引用类型变量:使用一个其他数据项的引用
在日常开发中最常用的是前两种类型。
--- 标量类型的变量
标量类型的变量是最简单类型的变量,也是普通开发者最常用的一种变量类型,它本身是单一的值,
不包含任何的类型组合。
标量类型主要包含数值类型、字符类型、布尔类型、日期类型。还有一种比较特殊的声明变量类型的
方式,就是利用 %TYPE 。下面对这几种类型做详细的介绍:
(1)、数值类型,主要用来存放数字型的数据。最常用的就是 NUMBER 、PLS_INTEGER 、
BINARY_INTEGER 、 SIMPLE_INTEGER 。
》》NUMBER 类型可以表示整数和浮点数,该类型以十进制存储。其通用格式是
NUMBER( precision , scale ) ,其中 precision 表示精度,也就是数字的位数,可达38位;
scale 表示小数点后的位数。
》》PLS_INTEGER 和 BINARY_INTEGER 类型通常可以认为是一样的类型。表示的范围是
-2 147 483 648 ~ 2 147 483 647 之间。二者不一样的地方就是 BINARY_INTEGER 发生
溢出的时候能为其指派一个 NUMBER 类型而不至于发生异常,但 PLS_INTEGER 溢出会
发生异常,建议使用 PLS_INTEGER 类型。
》》 SIMPLE_INTEGER 类型属于 PLS_INTEGER 的子类型,它的取值范围同 PLS_INTEGER
一样,只是该类型不允许为空。如果数据本身不需要溢出检查而且也不可能是空,那么可以选择
该类型,该类型的性能比 PLS_INTEGER 高。
(2)、字符类型,可以用来存储单个的字符或字符串的类型。主要有 CHAR 、 VARCHAR2 (VARCHAR)、
NCHAR 、 NVARCHAR2 、LONG 类型。
》》CHAR 类型,用来描述固定长度的字符串,最长为 32 767 个字节,默认是长度1 。该类型的
字符中如果值的长度达不到定义的长度,那么将以空格补齐。通常定义格式
CHAR( maximum_size ) 。一旦使用该类型,那么在数据库提取数据时可能要做空格处理。
》》 VARCHAR2 类型,作为变量的时候最长为 32 767 个字节,但作为字段存储的时候是4000
个字节。该类型表示可变长度的字符串。也就是说,当值的长度达不到定义的长度时,不用
空格补齐,这样就可以节省一定的空间。
》》 NCHAR 、 NVARCHAR2 类型使用方式同 CHAR 和 VARCHAR2 相同,只不过它们与
国家的字符集有关。
》》 LONG 类型,以可变的方式存储数据,PL/SQL 中作为变量可表示最长可达 32 760 字节的
字符串,如果作为存储字段则可达 2GB 。
(3)、布尔类型,它不能用做定义表中的数据类型。但PL/SQL中该类型可以用来存储逻辑上的值。它
有3个值可选:TRUE 、 FALSE 、 NULL 。
(4)、日期类型,主要有 DATE 和 TIMESTAMP
》》 TIME 类型可以存储月、年、日、世纪、时、分、秒
》》 TIMESTAMP 类型由 DATE 演变而来,可以存储月、年、日、世纪、时、分、秒以及小数
的秒
(5)、使用 %TYPE 方式定义变量类型。这种定义变量类型的方式和前面所介绍的直接定义变量类型
有所不同,它利用已经存在的数据类型来定义新数据的数据类型。最常见的就是把表中字段类型
作为变量或常量的数据类型。使用此种方式的好处有如下几点:
》》利用 %TYPE 定义的变量或常量数据类型都一致,当有变动的需求时,只要改变被引用的
变量或常量的数据类型,其他引用处的数据类型自然就变了,避免了逐条修改的麻烦。
》》 使用 PL/SQL语句块通常都是操作数据库表的数据,操作过程中避免不了出现数据的传递,
这时变量利用 %TYPE 就可以完全兼容提取的数据,而不至于出现数据溢出或不符的情况。
》》当利用 %TYPE 定义数据类型时,可以保证变量的数据类型和表中的字段类型同步,当表
字段类型发生变化时,PL/SQL 块变量的数据类型不需要修改。
【示例5】变量定义示例
DECLARE
v_productid productinfo.productid%TYPE -- 产品ID
v_productname VARCHAR2(20) -- 产品名称
v_productprice NUMBER(8,2) -- 产品价格
v_quantity NUMBER(10) -- 数量
v_desperation CONSTANT v_productname%TYPE := ' 测试'; -- 测试
v_spitgr SIMPLE_INTEGER := 99.9;
v_long LONG := 'LONG类型测试';
v_date DATE := SYSDATE;
BEGIN
select productid ,productname , productprice , quantity
into v_productid, v_productname , v_productprice , v_quantity
from productinfo
where productid = '0240040001';
DBMS_OUTPUT.PUT_LINE('v_productid = ' || v_productid );
...
...
END;
--- 复合类型的变量
*** 所谓复合类型的变量,就是每变量包含几个元素,可以存储多个值。这种变量类型同标量类型
使用方式稍有差异,复合类型需要先定义,然后才能声明该类型的变量。
最常用的是三种类型,一种是记录类型,一种是索引类型,还有一种是 VARRAY 数组。
*** PL/SQL “记录类型”
该类型可以包含一个或多个成员,而每个成员的类型可以不同,成员可以是标量类型,也可以是
引用其他变量的类型(使用 %TYPE)。该类型比较适合处理查询语句中有多个列的情况。
最常用的就是在调用某张表中的一行记录时,利用该类型变量存储这行记录。如果想要调用其中
的数据,可以用 “ 变量名称 . 成员名称 ” 的格式进行调用。“ 记录类型 ” 有两种声明的方式。
(1)、第一种声明语法如下:
01 TYPE type_name IS RECORD
02 (
03 field_name datatype
04 [
05 [ NOT NULL]
06 { := | DEFAULT } expression
07 ]
08 [ , field_name datatype [ [ NOT NULL] { := | DEFAULT } expression ] ...
09 ) ;
【语法说明】
》》第 1 行的 type_name 表示定义的记录类型的名称。其余的都是关键字。
》》第 3 行的 field_name 表示记录的成员名称, datatype 表示行记录成员数据类型。
》》第 5 行的 [ NOT NULL] 表示为可选部分,可以约束记录的成员非空。
》》第 6 行的 { := | DEFAULT } 表示为记录成员赋值 , expression 为赋值表达式。
》》第 8 行同第 3 ~ 7 行表示的含义相同,这么写让读者明白,记录类型里可以有多个
成员。
从上面语法介绍中可以看出记录类型可以包含多个成员,而其成员的定义方式和前面介绍的
标量定义方式相同。
【示例6】定义“ 记录类型 ” 的变量
DECLARE
TYPE product_rec IS RECORD
(
v_productid productinfo.productid%TYPE -- 产品ID
v_productname VARCHAR2(20) -- 产品名称
v_productprice NUMBER(8,2) -- 产品价格
);
v_product product_rec; -- 记录类型变量
BEGIN
select productid ,productname , productprice
into v_product
from productinfo
where productid = '0240040001';
DBMS_OUTPUT.PUT_LINE('v_productid = ' || v_product.v_productid );
DBMS_OUTPUT.PUT_LINE('v_productid = ' || v_product.v_productname );
DBMS_OUTPUT.PUT_LINE('v_productid = ' || v_product.v_productprice );
END;
/
(2)、利用 %ROWTYPE 声明记录型数据 (第二种声明语法)
前面介绍过 “ 记录类型 ” 的变量 ,该类型是提取行记录时常用的存储数据的方式。除了上面介绍
的直接声明方式外还有一种声明记录类型的方式,就是利用 %ROWTYPE 。这种声明方式可以直接
引用表中的行作为变量类型。它同 %TYPE 类似,可以避免因表中字段的数据类型改变而导致PL/SQL
块出错的问题。
【示例7】%ROWTYPE 示例
DECLARE
v_product productinfo%ROWTYPE ;
BEGIN
select *
into v_product
from productinfo
where productid = '0240040001';
DBMS_OUTPUT.PUT_LINE('v_productid = ' || v_product.productid );
DBMS_OUTPUT.PUT_LINE('v_productid = ' || v_product.productname );
DBMS_OUTPUT.PUT_LINE('v_productid = ' || v_product.productprice );
END;
/
补充:该示例同上一个示例结果是一样的,但是这个示例却使用更少的代码完成了同一个功能。
*** PL/SQL 索引表类型(关联数组)
该类型和数组相似,它利用键值查找对应的值。这里键值同真正数组的下标不同,索引表中下标允许使
用字符串。数组的长度不是固定值,它可以根据需要自动增长。其中的键值是整数或字符串。而其中的值就是
普通的标量类型,也可以是记录类型。可以利用 “ 变量名称(键值) ” 为其赋值或取值,如果某个键值的指向
已经有数据了,那么该操作就是更改已有的数据。具体的语法如下:
--------------------------------------------------------------------------------------------
01 TYPE type_name IS TABLE OF
02 {
03 column_type |
04 variable_name%TYPE |
05 table_name.column_name%TYPE |
06 table_name%ROWTYPE
07 }
08 [ NOT NULL ]
09 INDEX BY { PLS_INTEGER | BINARY_INTEGER | VARCHAR2 ( v_size ) }
---------------------------------------------------------------------------------------------------
【语法说明】
》》第 1 行的 type_name 表示该类型的名称。其他为固有关键词。
》》第 3 ~ 6 行表示索引表中的数据类型。其中,第 3 行表示标量数据类型 ,第 4 和 5 行表示利用
%TYPE 引用类型 ,第 6 行利用 %ROWTYPE 引用类型。
》》第 8 行表示是否可以为空的约束。
》》第 9 行表示数组下标的数据类型。
以上的语法只是索引表类型本身的定义语法,并没有包含变量的定义。实际上,这里和变量的定义没有
关系。如果想把某个变量声明成索引表类型,按照下面语法就好:
variable_name type_name
其中,variable_name 就是变量的名称,而 type_name 就是索引表的名称。日常开发中可以选择用数字
作为键值或以字符串作为键值。下面的两个示例将演示如何使用者两种方式操作:
【示例8】 数字作为键值的索引表示例
DECLARE
TYPE prodt_tab_fst IS TABLE OF
productinfo%ROWTYPE
INDEX BY BINARY_INTEGER; --索引值为 BINARY_INTEGER 类型
TYPE prodt_tab_sec IS TABLE OF
VARCHAR2( 8 )
INDEX BY PLS_INTEGER; --索引值为 BINARY_INTEGER 类型
v_prt_row prodt_tab_fst;
v_prt prodt_tab_sec;
BEGIN
v_prt(1) := '正数';
v_prt(-1) := '负数';
select *
into v_prt_row(1)
from productinfo
where productid = '0240040001';
DBMS_OUTPUT.PUTLINE('行数据-v_prt_row(1) = '|| v_prt_row(1).productid
|| '-------'
|| v_prt_row(1).productname );
DBMS_OUTPUT.PUTLINE('v_prt(1) = ' || v_prt(1) );
DBMS_OUTPUT.PUTLINE('v_prt(-1) = ' || v_prt(-1) );
END;
/
【示例9】字符串作为键值的索引表
DECLARE
TYPE prodt_tab_thd IS TABLE OF
NUMBER(8)
INDEX BY VARCHAR2(20); --索引值为 VARCHAR2(20) 类型
v_prt_chr prodt_tab_thd;
BEGIN
v_prt_chr('test') := 123 ;
v_prt_chr('test1') := 0 ;
DBMS_OUTPUT.PUT_LINE('v_prt(1) = ' || v_prt_chr('test') );
DBMS_OUTPUT.PUT_LINE('v_prt(-1) = ' || v_prt_chr('test1') );
DBMS_OUTPUT.PUT_LINE('v_prt(-1) = ' || v_prt_chr.first);
DBMS_OUTPUT.PUT_LINE('v_prt(-1) = ' || v_prt_chr(v_prt_chr.first));
END;
/
【执行效果】
*** VARRAY 变长数组
该类型的元素个数是需要限制的,它是一个存储有序元素的集合。集合下标从 1 开始,比较适合
较少的数据使用。声明语法如下:
-------------------------------------------------------------
TYPE type_name IS { VARRAY | VARYING ARRAY } ( size_limit )
OF element_type [ NOT NULL ]
-------------------------------------------------------------
【语法说明】
》》type_name : 表示数组的名称
》》{ VARRAY | VARYING ARRAY } :必选项,二选一,表示数组类型
》》 size_limit : 表示数组的长度
》》 element_type :数组里元素的类型
【示例10】VARRAY 数组示例
01 DECLARE
02 TYPE varr IS VARRAY(100) OF VARCHAR2(20) ;
03 v_product varr := varr('1','2');
04 BEGIN
05 v_product(1) := 'THIS IS A';
06 v_product(2) := 'TEST';
07 DBMS_OUTPUT.PUT_LINE('v_product(1) = ' || v_product(1));
08 DBMS_OUTPUT.PUT_LINE('v_product(2) = ' || v_product(2));
09 END;
10 /
【代码解析】
》》 第 2 行表示声明 VARRAY 数组,数组长度为100 , 名称是 varr ,元素为 VARCHAR2
类型,长度为 20
》》 第 3 行表示声明变量,变量名称为 v_product ,其类型为 varr 类型,其类型被初始化了
两个元素(最多可初始化100个)。也就是说,只能向 v_product 中下标为 1 和 2 的元素赋值。
》》第 5~6 行表示为数组元素赋值。
》》第 7~8行表示输出数组元素的值。
【执行效果】