1.作用域
变量的作用域是指变量的有效作用范围,它从变量声明开始,直到当前块结束。只有在其作用域范围之内,程序才能使用该变量,否则将导致编译错误。
<<block>> DECLARE v_1 VARCHAR2 (30) := 'block中的全局v1'; BEGIN DBMS_OUTPUT.put_line (v_1); <<subblock_1>> DECLARE v_1 VARCHAR2 (30) := 'subblock_1中的局部v1'; BEGIN DBMS_OUTPUT.put_line (v_1); DBMS_OUTPUT.put_line (block.v_1); END; <<subblock_2>> DECLARE v_1 VARCHAR2 (30) := 'subblock_2中的局部v1'; BEGIN DBMS_OUTPUT.put_line (v_1); DBMS_OUTPUT.put_line (block.v_1); END; END; /
2.用SELECT INTO语句给变量赋值
除了用常量给变量赋值之外,还可以从数据库表中查询出值来赋予变量。
DECLARE v_bonus NUMBER (8, 2); v_empno NUMBER (6) := 7369; BEGIN SELECT sal * 0.10 INTO v_bonus FROM emp WHERE empno = v_empno; DBMS_OUTPUT.put_line ( '雇员' || TO_CHAR (v_empno) || '的奖金是:' || TO_CHAR (v_bonus)); END; /
3.TIMESTAMP(s)
TIMESTAMP是DATE数据类型的扩展。存储了年、月、日、时、分、秒,秒带有小数,还包括了上午、下午、时区。其中后面的(s)是可选的,s表示秒部分的小数位位数,s的取值范围是s=0~9。默认的TIMESTAMP格式是由初始化参数NLS_TIMESTAMP_FORMAT来设置的。
DECLARE v_datetime TIMESTAMP (9); BEGIN v_datetime := SYSTIMESTAMP; DBMS_OUTPUT.put_line (v_datetime); END; /
4.%TYPE
为了使一个变量的数据类型与另一个已经定义了的变量(尤其是表的某一列)的数据类型相一致,Oracle提供了%TYPE定义方式。这样,当被参照的那个变量的数据类型改变了之后,这个新定义的变量的数据类型也自动跟随其改变,容易保持一致,也不用修改PL/SQL程序了。当不能确切地知道被参照的那个变量的数据类型时,只能采用这种方法定义变量的数据类型。
DECLARE v_ename emp.ename%TYPE; v_sal emp.sal%TYPE; c_tax_rate CONSTANT NUMBER (3, 2) := 0.03; v_sal_tax v_sal%TYPE; BEGIN SELECT ename, sal INTO v_ename, v_sal FROM emp WHERE empno = &eno; v_sal_tax := v_sal * c_tax_rate; DBMS_OUTPUT.put_line ('雇员名称:' || v_ename); DBMS_OUTPUT.put_line ('工资:' || v_sal); DBMS_OUTPUT.put_line ('所得税:' || v_sal_tax); END; /
5.%ROWTYPE
如果一个表有较多的列,使用%ROWTYPE来定义一个表示表中一行记录的变量,比分别使用%TYPE来定义表中的各列的变量要简捷得多,并且不容易遗漏、出错。这会增加程序的可维护性。
DECLARE v_emp emp%ROWTYPE; BEGIN SELECT * INTO v_emp FROM emp WHERE empno = &eno; DBMS_OUTPUT.put_line ('雇员名称:' || v_emp.ename); DBMS_OUTPUT.put_line ('工资:' || v_emp.sal); DBMS_OUTPUT.put_line ('岗位:' || v_emp.job); END; /
6.RECORD
定义记录数据类型。它类似于C语言中的结构数据类型(STRUCTURE),PL/SQL提供了将几个相关的、分离的、基本数据类型的变量组成一个整体的方法,即RECORD符合数据类型。在使用记录数据类型变量时,需要在声明部分先定义记录的组成、记录的变量,然后在执行部分引用这记录变量本身或其中的的成员。
DECLARE TYPE emp_record_type IS RECORD ( name emp.ename%TYPE, salary emp.sal%TYPE, job emp.job%TYPE ); v_emp_record emp_record_type; BEGIN SELECT ename, sal, job INTO v_emp_record FROM emp WHERE empno = &eno; DBMS_OUTPUT.put_line ( '雇员名称:' || v_emp_record.name || '工资:' || v_emp_record.salary || '岗位:' || v_emp_record.job); END; /
7.TABLE
定义记录表(或索引表)数据类型。它与记录类型相似,但它是对记录类型的扩展。它可以处理多行记录,类似于C语言中的二维数组,使得可以在PL/SQL中模仿数据库中的表。关键字INDEX BY表示创建一个主键索引,以便引用记录表变量中的特定的行。
DECLARE TYPE emp_table_type IS TABLE OF emp%ROWTYPE INDEX BY BINARY_INTEGER; v_emp_table emp_table_type; BEGIN SELECT ename, sal INTO v_emp_table (1).ename, v_emp_table (1).sal FROM emp WHERE empno = 7369; SELECT ename, sal INTO v_emp_table (2).ename, v_emp_table (2).sal FROM emp WHERE empno = 7788; DBMS_OUTPUT.put_line ( '7369雇员名称:' || v_emp_table (1).ename || ' 工资:' || v_emp_table (1).sal); DBMS_OUTPUT.put_line ( '7788雇员名称:' || v_emp_table (2).ename || ' 工资:' || v_emp_table (2).sal); END; /可以看出,记录表可以存储多行、多列的数据,就好像在PL/SQL中创建的一个表,所以也被称为PL/SQL表。