一、变量介绍
在编写pl/sql程序时,可以定义变量和常量;在pl/sql程序中包括有:
- 标量类型(scalar)
- 复合类型(composite) --用于操作多条记录
- 参照类型(reference) --用于操作多条记录,存放指针
- lob(large object)
二、标量类型
变量初始化和关键字:
identifier [CONSTANT] datatype [NOT NULL] [:= | DEFAULT expr];
- identifier 变量名
- [CONSTANT] 指定常量。需要指定它的初始值,且其值是不能改变的
- [NOT NULL] 必须初始化,不能被赋予NULL值
- := 赋值操作符
- DEFAULT 用于指定初始值
- expr :指定初始值的pl/sql表达式,可以是文本值、其它变量、函数等
演示:
declare v_city varchar2(30) NOT NULL := 'Beijing'; v_location varchar2(13) := 'Atlanta'; v_deptno number(2) NOT NULL := 10; v_mgr number(6) DEFAULT 100; v_hiredate date; v_date date := to_date('20110117','yyyymmdd'); v_rowid rowid; b_flag boolean; begin null; end; /
PL/SQL变量和数据库变量长度区别:
- CHAR 32767BYTE
- VARCHAR2 32767BYTE
- LONG 32760BYTE 2G
- LONG RAW 32760BYTE 2G
列名的优先级别高于变量!所以不要重名.
declare ename varchar2(20) :='KING'; begin delete emp where ename=ename; end; /
变量输出测试
例题一:创建一个匿名PL/SQL块,将下列字符输出到屏幕:"today is : 在此处显示当前时间"
set serveroutput on ----打开允许客户端输出 begin DBMS_OUTPUT.PUT_LINE('today is : '||sysdate); end; /
变量的作用范围,相当于父子进程之间的变量传递
declare v_var1 number := 123; begin dbms_output.put_line('OUT: v_var1 :'||v_var1); declare v_var2 number := 456; begin dbms_output.put_line('IN: v_var1 :'||v_var1); dbms_output.put_line('IN: v_var2 :'||v_var2); END; -- dbms_output.put_line('IN: v_var2 :'||v_var2); 内部块中的变量不能被外部块使用. 去掉注释则报错 end; / 输出结果: OUT: v_var1 :123 IN: v_var1 :123 IN: v_var2 :456 PL/SQL procedure successfully completed.
语句块的标签
标签加载一个语句块开始的位置上。
当外部块和内部块出现同名变量时,借助标签来区分,但这样的程序可读性太差,尽量不要使变量名重复。
<<outer>> declare v_var1 number := 123; begin dbms_output.put_line('OUT: v_var1 :'||v_var1); <<inner>> declare v_var1 number := 456; begin dbms_output.put_line('IN: v_var1 :'||v_var1); dbms_output.put_line('IN: outer v_var1 :'||outer.v_var1); END inner; end outer; / SQL> / OUT: v_var1 :123 IN: v_var1 :456 IN: outer v_var1 :123 PL/SQL procedure successfully completed.
PL/SQL中select语句的运用
declare v_ename varchar2(20); v_job varchar2(20); v_sal number; v_date date; v_info varchar2(100); begin /* select ename,job,sal,hiredate into v_ename,v_job,v_sal,v_date from scott.emp where ename='KING'; dbms_output.put_line(v_ename||' '||v_job||' '||v_sal||' '||v_date); */ select ename||' '||job||' '||sal||' '||hiredate into v_info from scott.emp where ename='KING'; dbms_output.put_line(v_info); end; /
需要定义变量,然后into到变量中。可以定义几个变量,也可以把列用||连接,作为一个字符串into到一个变量中。
三、复合类型
由原来的普通标准变量存一个单行单列的值,增强到了存单行多列的值。
1、数组
先定义数组的类型,再将类型赋予变量,变量就变成了数组 (后面的record和plsql_table同理)。
declare type no_list is varray(10) of number; --varray(10)表示数组个数为10,number表示存储数字类型 x no_list :=no_list(1990,2010,1995); begin dbms_output.put_line('no_list 1 is:'||x(1)); dbms_output.put_line('no_list 2 is:'||x(2)); dbms_output.put_line('no_list 3 is:'||x(3)); end; /
2、记录(record)
使用方法:
- 先定义类型,类型中描述了这是一个RECORD
- 但却没有说明内部具体列的内容,定义自定义类型就是为了定义record内部都包含什么列.
- 再将定义好的类型关联一个变量
引用record类型中的值:记录名.内部列名
举例:声明一个变量用来保存emp表的部分列的数据。
declare --第一个变量声明 v_sal number(7,2); --第二个变量声明 TYPE emp_record_type IS RECORD (ename VARCHAR2(25), job VARCHAR2(10), sal NUMBER(7,2)); emp_record emp_record_type; begin emp_record.ename := 'Alvin'; emp_record.job := 'clerk'; emp_record.sal := 1000; dbms_output.put_line(emp_record.ename||' '||emp_record.job||' '||emp_record.sal); end; /
3、PL/SQL表(INDEX BY表)
类似于数组,但下标除了定义成数字外还可以定义为字符,定义成数值型下标时必须使用binary_integer类型。
binary_integer类型相比number类型区别:
- 存储的数据以二进制方式存储,占用更少的空间
- 可以存储 -2147483747 - 2147483747之间的任意整数
- 主要使用在PL/SQL表的下标类型上,不能出现在常规列的类型上,反之PL/SQL表的下标也不能使用number来取代
使用方法:
- 先定义类型 指出下标是数字还是字符
- 再类型关联变量
- 引用PL/SQL表中的元素:表名(下标)
举例:
declare type emp_table_type is table of varchar2(20) index by binary_integer; emp_table emp_table_type; begin emp_table(0) :='Alex'; emp_table(-1) :='X1'; emp_table(2) :='hello'; dbms_output.put_line('index 0 : '||emp_table(0)); dbms_output.put_line('index -1 : '||emp_table(-1)); dbms_output.put_line('index 2 : '||emp_table(2)); end; /
特殊关键字引用方法:
declare type emp_table_type is table of varchar2(10) index by varchar2(10); emp_table emp_table_type; begin emp_table('A') := 'KING'; emp_table('B') := 'zjz'; dbms_output.put_line('PL/SQL table elements numbers : '||emp_table.count); dbms_output.put_line('The first element index --> '||emp_table.first); dbms_output.put_line('The last element index --> '||emp_table.last); dbms_output.put_line('The index ''B'' prior element is --> '||emp_table.prior('B')); dbms_output.put_line('The index ''A'' next element is --> '||emp_table.next('A')); end; /
4、PL/SQL表+record
PL/SQL中不能直接使用select 需要使用select into 将查询结果插入到标量 再dbms_output打印标量
使用方法:
- 先定义record类型,声明类型中包含哪些列
- 再定义PL/SQL类型,PL/SQL表类型关联之前定义的record类型
- 这样就将record作为了PL/SQL表中的元素
- 再将PL/SQL类型关联到变量
引用方法:
- 赋值:PL/SQL表名(下标)
- 取值:PL/SQL表名(下标).record中的列名
declare TYPE emp_record_type IS RECORD (ename VARCHAR2(25), job VARCHAR2(10), sal NUMBER(7,2)); type emp_table_type is table of emp_record_type index by binary_integer; emp_table emp_table_type; begin select ename,job,sal bulk collect into emp_table from scott.emp; for i in emp_table.FIRST..emp_table.LAST loop dbms_output.put_line('index'|| i ||' : '||emp_table(i).ename); end loop; end; /
四、参照变量
参照变量是指用于存放数值指针的变量。通过使用参照变量,可以使得应用程序共享相同对象,从而降低占用的空间。在编写pl/sql程序时,可以使用游标变量(ref cursor)和对象类型变量(ref obj_type)两种参照变量类型。
1、ref cursor游标变量
使用游标时,当定义游标时不需要或不能指定相应的select语句,但是当使用游标时(open 时)需要指定select语句,这样一个游标与一个select语句结合了。实例如下:
- 请使用pl/sql编写一个块,可以输入部门号,并显示该部门所有员工姓名和他的工资。
- 在1的基础上,如果某个员工的工资低于200元,就添加100元。
SET serveroutput ON; DECLARE --定义游标 TYPE sp_emp_cursor IS REF CURSOR; --定义一个游标变量 sp sp_emp_cursor; --定义变量 v_ename emp.ename%TYPE; v_sal emp.sal%TYPE; BEGIN OPEN sp FOR SELECT e.ename, e.sal FROM emp e WHERE e.deptno=10; --方法一 loop循环 /* LOOP FETCH sp INTO v_ename, v_sal; EXIT WHEN sp%NOTFOUND; DBMS_OUTPUT.PUT_LINE('名字:' || V_ENAME || ' 工资:' || V_SAL); END LOOP;*/ --方法二 while循环 /* WHILE 1=1 LOOP FETCH sp INTO v_ename, v_sal; EXIT WHEN sp%NOTFOUND; DBMS_OUTPUT.PUT_LINE('名字:' || V_ENAME || ' 工资:' || V_SAL); END LOOP;*/ END; /