前言:
使用变量可以保存计算机需要处理的数据,为了给该变量分配适当的内存空间,还需要指定数据类型,有的数据类型还需要指定长度,如字符串。
有些类型可以用于建表(char),有些则不能(booleanrowtype)
同样是字符串,建表时的限制为4000,在脚本中则为3万多。
简单语法:变量名 数据类型;
完整语法:变量名 [constant] 变量类型 [not null] [default | :=]
其中“[ ]”表示可以不写,“|”表示任选其一。
下面给出变量定义及解释,数据类型先用建表时所用的数据类型:
v1 char
说明:没有给出长度,所以v1只能保存一个字符。超过了则会出错:数字或值错误 : 字符串缓冲区太小。
v2 varchar2(10);
说明:v2最多只能保存10个字符。如果不写长度,会出错:字符串长度限制在范围(1...32767)
v3 number;
说明:v3保存的数字范围非常大,几乎可以认为是没有限制的。
v4 number(5);
说明:v4最多能够保存5位整数。如果有小数,Oracle会自动四舍五入。如果整数部分超过5位,则会报错:数字或值错误 : 数值精度太高。
v5 number(5,2);
说明:v5最多能够保存3位整数,2位小数。如果小数位不止2位,则Oracle会自动四舍五入。整数位超过3位会报错,同上。
v6 date;
说明:可以直接保存sysdate的值;如果是指定日期,则要用to_date来转化。否则报错:文字与格式字符串不匹配。
定义了变量,变量的默认值为空,此时进行计算,结果一定为NULL。所以变量必须初始化。
初始化有三种方式:
v7 constant number := 100;
说明:定义v7为常量,定义时就必须给定值。然后在程序中就不能再对v7进行赋值了,否则会报错:表达式 'V7' 不能用作赋值目标。
v8 number default 10;
说明:定义v8时就给定默认值10。注意,number类型变量的默认值不是0,而是NULL
v9 number not null := 1000.50;
说明:定义v9变量不能为空,此时必须给出一个不为NULL的值。在运行时发现v9NULL,则报错:说明为 NOT NULL 的变量必须有初始化赋值。
预测各打印结果,如果代码有错误请先改正:
declare
v1 char;
v2 varchar2(10);
v3 number;
v4 number(5);
v5 number(5,2);
v6 date;
v7 number default 10;
begin
v1:='ab';
v2:='abcd';
v4:=9998.99;
v5:=1000.5555555;
v6:=to_date('2002-10-2','yyyy-mm-dd');
dbms_output.put_line(v1);
dbms_output.put_line(v2);
dbms_output.put_line(v3+100);
dbms_output.put_line(v4);
dbms_output.put_line(v5);
dbms_output.put_line(v6);
dbms_output.put_line(v7+100);
end;
只能在脚本中使用的变量类型:
上面的数据类型,同时在建表时也能使用。而下面的数据类型只能在PL/SQL脚本中使用。
即:booleantyperowtyperecord,替代变量、table类型。
其中:
·一个变量只能保存一个值,叫做标量变量。如:chartype
·一个变量只能保存多个值,叫做复合变量。如:rowtyperecord,table
1、布尔类型 boolean
boolean类型主要表达真或假。可以为boolean类型变量赋值truefalse
主要用于PL/SQL脚本的流程控制。
示例:
declare
v1 boolean;
begin
v1:=1>2;
dbms_output.put_line(v1);
end;
问题:打印的结果是什么,是truefalse10
回答:
都不对。运行时得到错误信息:调用 'PUT_LINE' 时参数个数或类型错误。
这是因为在脚本中不能直接打印boolean类型的值,所以只能在脚本中使用if语句来判断。
修改示例:
declare
v1 boolean;
begin
v1:=1>2;
if(v1)then
    dbms_output.put_line('');
else
    dbms_output.put_line('');
end if;
end;
打印:
2type类型。
语法:表.字段%TYPE
返回:某个表的字段的实际类型。
作用:
PL/SQL脚本中,有时定义的变量就是存取表中数据的。此时数据类型及长度就需要与字段
的定义一致。可以去查看该字段的具体类型,但这样做很麻烦;并且当字段定义改变时,脚本也需要修改。
所以使用type类型来引用该字段的类型,更方便,维护性更好。

示例:根据工号查询员工姓名。
分析:要从emp表中获取姓名,必须要用查询语句。而要从查询语句中获取返回的值,要加上“into 变量
declare
    v_pno%type;
    v_ame%type;
begin
    v_empno:=7900;
    select ename into v_ename from emp where empno=7900;
    dbms_output.put_line(v_ename);
end;

3rowtype类型
语法: %rowtype
作用: 保存了某一行记录的所有字段的值。

示例:根据工号为7900的员工的以下信息:ename,job,sal,comm,hiredate
第一种:如果用type类型,定义5个变量保存查询结果。代码略。
第二种:如果用rowtype类型,只需要定义一个rowtype类型的变量。
代码:
declare
    v_pno%type;
    v_row emp%rowtype;
begin
    v_empno:=7900;
    select * into v_row from emp where empno=7900;
    dbms_output.put_line('ename='||ame);
    dbms_output.put_line('job='||v_row.job);
    dbms_output.put_line('sal='||v_row.sal);   
    dbms_output.put_line('comm='||v_rowm);
    dbms_output.put_line('hiredate='||v_row.hiredate);   
end;
打印:
ename=JAMES
job=CLERK
sal=950
comm=
hiredate=03-12-81
说明
·必须select *,或者根据表结构的顺序写出所有字段名。
·
使用oracle四舍五入rowtype类型最主要的限制在于表中不能有大对象字段如:CLOBBLOB
4record类型
record的意思是记录
有时,用type类型会定义太多的变量,用rowtype又会取到自己不关心的数据。
如何只取自己关心的字段的值呢?此时就用record类型来自定义有多少个列。
语法:
type 类型名 is record(
  属性名1 属性类型,
  属性名2 属性类型
);
注意
1、属性之间定义用的是逗号(,),不是分号(;)
2、最后一个属性名不需要再用
使用步骤有两个:
1、先用type自定义一个新的类型,这个类型的变量能够的变量与定义有关。
2、再用这个新的类型来定义一个变量,这个变量才能保存实际的数据。
示例:需求同上。
declare
--自定义一个类型
type myType is record(
    ame%type, --姓名
    gzuo emp.job%type, --工作
    gzi emp.sal%type --工资
);
--使用自定义类型来定义变量
myValue myType;
begin
    select ename,job,sal into myValue from emp where empno=7844;
    dbms_output.put_line('ename='||);
    dbms_output.put_line('job='||uo);
    dbms_output.put_line('sal='||i);
end;

说明:
· 在查询时必须与自定义类型的属性顺序一一对应。
·myValue中的属性名也是自定义的,不是字段名。

问题:上面的代码比直接用type类型还多些,看不出优势在什么地方。为什么还要用record
回答:
在项目中,自定义类型通常会放到在包(package,后面会专门学习)中,这样就可以在其它地方直接引用了。

示例:
先在包中自定义类型:
create or replace package my_bao
as
type myType is record(
    ame%type, --姓名
    gzuo emp.job%type, --工作
    gzi emp.sal%type --工资
);
end;
然后就可以在块中直接使用该类型,只不过在类型前要加上包名:my_bao”。
declare
--使用包中自定义类型来定义变量
myValue Type;
begin
    select ename,job,sal into myValue from emp where empno=7844;
    dbms_output.put_line('ename='||);
    dbms_output.put_line('job='||uo);
    dbms_output.put_line('sal='||i);
end;

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。