在Oracle数据库中,var
的使用主要涉及到PL/SQL中的变量定义以及SQL*Plus中的变量定义和引用。以下是关于Oracle中var
的详细解释:
1、PL/SQL中的变量定义
- 在PL/SQL中,变量用于存储数据值。这些变量可以是内置数据类型(如NUMBER, VARCHAR2, DATE等)或用户定义的数据类型。
- 变量定义的语法为:
DECLARE variable_name datatype(size);
其中variable_name
是变量名,datatype
是数据类型,(size)
(如果适用)是数据类型的大小。 - 例如:
DECLARE v_name VARCHAR2(50);
- 在PL/SQL块(如存储过程、函数或匿名块)中,可以在
DECLARE
部分定义变量。
2、SQL*Plus中的变量定义和引用
- 在SQL*Plus中,可以使用
var
命令来定义变量。这些变量是绑定变量,可以在SQL语句中引用。 - 定义语法为:
VAR[IABLE] [variable_name] [datatype] [:= value];
其中variable_name
是变量名,datatype
是数据类型,:= value
(可选)是变量的初始值。 - 例如:
VAR v_empno NUMBER;
- 引用SQL*Plus中定义的变量时,需要在变量名前加上冒号(
:
)。例如,在查询中使用该变量:SELECT * FROM employees WHERE employee_id = :v_empno;
- 变量定义后,可以使用
PRINT
命令来显示变量的值:PRINT v_empno;
- 在SQL*Plus中,定义的变量也可以在PL/SQL块中引用,但需要使用不同的语法(如
BIND
命令或直接在PL/SQL块中引用)。
3、注意事项
- 在PL/SQL中定义的变量只能在定义它的PL/SQL块内部访问。
- 在SQL*Plus中定义的变量可以在多个SQL语句和PL/SQL块之间共享。
- 在SQLPlus中,使用
var
定义的变量是会话特定的,即它们只存在于当前的SQLPlus会话中。 - 当在SQL*Plus中使用绑定变量时,可以提高SQL的执行性能,因为Oracle可以重用执行计划和缓存结果。
4、示例使用var定义变量
SYS@orcl>var v_string VARCHAR2(100);
SYS@orcl>exec :v_string :='hello pl/sql';
PL/SQL procedure successfully completed.
SYS@orcl>BEGIN
2 DBMS_OUTPUT.PUT_LINE(:v_string);
3 END;
4 /
hello pl/sql
PL/SQL procedure successfully completed.
-- 使用print打印
SYS@orcl>PRINT v_string;
V_STRING
---------------------------------------------------
hello pl/sql
-- select clause通过查询字句
SYS@orcl>select :v_string from dual;
:V_STRING
----------------------------------------------------
hello pl/sql
-- 使用`var`命令来定义变量。这些变量是绑定变量,可以在SQL语句中引用
SYS@orcl>var x number;
SYS@orcl>exec :x :=20;
PL/SQL procedure successfully completed.
SYS@orcl>select * from emp where DEPTNO=:x;
EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO
---------- ------------------------------ --------------------------- ---------- ------------------- ---------- ---------- ----------
7369 SMITH CLERK 7902 1980-12-17 00:00:00 800 0 20
7566 JONES MANAGER 7839 1981-04-02 00:00:00 2975 0 20
7788 SCOTT ANALYST 7566 1987-04-19 00:00:00 3000 0 20
7876 ADAMS CLERK 7788 1987-05-23 00:00:00 1100 0 20
7902 FORD ANALYST 7566 1981-12-03 00:00:00 3000 0 20
-- 使用`var`命令来定义变量。这些变量是绑定变量,可以在SQL语句中引用
SYS@orcl>var v_deptno number;
SYS@orcl>exec :v_deptno :=20;
PL/SQL procedure successfully completed.
SYS@orcl>select EMPNO,ENAME,SAL from emp where DEPTNO=:v_deptno;
EMPNO ENAME SAL
---------- ------------------------------ ----------
7369 SMITH 800
7566 JONES 2975
7788 SCOTT 3000
7876 ADAMS 1100
7902 FORD 3000
5、示例使用declare定义变量
定义变量并赋值表中特定单行数据的特定列信息
-- 第一种定义方法,变量类型直接指定类型
declare v_EMPNO number :=7369;
v_ENAME VARCHAR2(32);
v_sal NUMBER(7,2);
begin
select ename,SAL INTO v_ENAME,v_sal
from emp
where EMPNO=v_EMPNO;
dbms_output.put_line(' run dbms_output.put_line is --> '|| '员工姓名: '||v_ENAME || ' 员工编号: '|| v_EMPNO || ' 员工薪水: '|| v_sal );
end;
/
-- 执行结果如果
run dbms_output.put_line is --> 员工姓名: SMITH 员工编号: 7369 员工薪水: 800
PL/SQL procedure successfully completed.
-- 第二种定义方法,变量类型依赖参照表字段类型
DECLARE
v_EMPNO number :=7369;
--自定义一个记录类型 emp_record_type
TYPE emp_record_type IS RECORD(v_ENAME emp.ENAME%TYPE,v_sal emp.SAL%TYPE);
--自定义一个变量 类型为上一步定义的emp_record_type
v_record emp_record_type;
BEGIN
select ENAME,SAL INTO v_record
from emp
where EMPNO=v_EMPNO;
dbms_output.put_line(' run dbms_output.put_line is --> '|| '员工姓名: '||v_ENAME || ' 员工编号: '|| v_EMPNO || ' 员工薪水: '|| v_sal );
END;
/
-- 执行结果如果
run dbms_output.put_line is --> 员工姓名: SMITH 员工编号: 7369 员工薪水: 800
PL/SQL procedure successfully completed.
定义变量并赋值表中特定多行数据的特定列信息,需要游标循环输出查询结果
DECLARE
TYPE emp_cursor_type IS REF CURSOR;--定义游标类型
v_cursor emp_cursor_type;--定义游标变量
v_deptno emp.DEPTNO%TYPE :=20;
v_empno emp.EMPNO%TYPE;
v_ename emp.ENAME%TYPE;
v_sal emp.SAL%TYPE;
BEGIN
--游标变量v_cursor
OPEN v_cursor FOR SELECT empno,ename,sal FROM emp WHERE deptno=v_deptno;
LOOP
--循环取出
FETCH v_cursor INTO v_empno,v_ename,v_sal;
--判断循环结束条件
EXIT WHEN v_cursor%NOTFOUND;
dbms_output.put_line(' run dbms_output.put_line is --> '|| '员工姓名: '||v_ENAME || ' 员工编号: '|| v_EMPNO || ' 员工薪水: '|| v_sal );
END LOOP;
CLOSE v_cursor;
END;
/
-- 执行结果如果
run dbms_output.put_line is --> 员工姓名: SMITH 员工编号: 7369 员工薪水: 800
run dbms_output.put_line is --> 员工姓名: JONES 员工编号: 7566 员工薪水: 2975
run dbms_output.put_line is --> 员工姓名: SCOTT 员工编号: 7788 员工薪水: 3000
run dbms_output.put_line is --> 员工姓名: ADAMS 员工编号: 7876 员工薪水: 1100
run dbms_output.put_line is --> 员工姓名: FORD 员工编号: 7902 员工薪水: 3000
PL/SQL procedure successfully completed.
6、用到测试表及数据准备
create table dept(deptno int primary key ,dname varchar2(16),loc varchar2(50));
INSERT INTO dept VALUES (10,'ACCOUNTING','NEW YORK');
INSERT INTO dept VALUES (20,'RESEARCH','DALLAS');
INSERT INTO dept VALUES (30,'SALES','CHICAGO');
INSERT INTO dept VALUES (40,'OPERATIONS','BOSTON');
commit;
comment on column dept.deptno is '部门编号';
comment on column dept.dname is '部门名称';
comment on column dept.loc is '部门所在位置';
comment on table dept is '员工部门表';
create table salgrade(grade int primary key,losal int,hisal int);
comment on column salgrade.grade is '工资等级';
comment on column salgrade.losal is '此等级的最低工资';
comment on column salgrade.hisal is '此等级的最高工资';
comment on table salgrade is '工资等级表';
set lin 300
col TABLE_NAME format a30
col column_name format a30
col COMMENTS format a60
select table_name,column_name,comments from user_col_comments where table_name='SALGRADE';
INSERT INTO salgrade VALUES (1,700,1200);
INSERT INTO salgrade VALUES (2,1201,1400);
INSERT INTO salgrade VALUES (3,1401,2000);
INSERT INTO salgrade VALUES (4,2001,3000);
INSERT INTO salgrade VALUES (5,3001,9999);
commit;
select * from salgrade;
create table bonus( ename varchar2(10),job varchar2(9),sal decimal(7,2),comm decimal(7,2));
comment on column bonus.ename is '雇员姓名';
comment on column bonus.job is '雇员职位';
comment on column bonus.sal is '雇员工资';
comment on column bonus.comm is '雇员奖金';
comment on table bonus is '雇员奖金表';
create table emp(
empno int primary key,
ename varchar2(15),
job varchar2(10),
mgr int,
hiredate date,
sal decimal(7,2),
comm decimal(7,2),
deptno int,
foreign key(deptno) references dept(deptno)
);
comment on column emp.empno is '雇员编号';
comment on column emp.ename is '雇员姓名';
comment on column emp.job is '雇员职位';
comment on column emp.mgr is '雇员对应的领导的编号';
comment on column emp.hiredate is '雇员的雇佣日期';
comment on column emp.sal is '雇员的基本工资';
comment on column emp.comm is '奖金';
comment on column emp.deptno is '所在部门';
comment on table emp is '雇员信息表';
INSERT INTO emp VALUES (7369,'SMITH','CLERK',7902,'1980-12-17',800,NULL,20);
INSERT INTO emp VALUES (7499,'ALLEN','SALESMAN',7698,'1981-2-20',1600,300,30);
INSERT INTO emp VALUES (7521,'WARD','SALESMAN',7698,'1981-2-22',1250,500,30);
INSERT INTO emp VALUES (7566,'JONES','MANAGER',7839,'1981-4-2',2975,NULL,20);
INSERT INTO emp VALUES (7654,'MARTIN','SALESMAN',7698,'1981-9-28',1250,1400,30);
INSERT INTO emp VALUES (7698,'BLAKE','MANAGER',7839,'1981-5-1',2850,NULL,30);
INSERT INTO emp VALUES (7782,'CLARK','MANAGER',7839,'1981-6-9',2450,NULL,10);
INSERT INTO emp VALUES (7788,'SCOTT','ANALYST',7566,'1987-7-13',3000,NULL,20);
INSERT INTO emp VALUES (7839,'KING','PRESIDENT',NULL,'1981-11-17',5000,NULL,10);
INSERT INTO emp VALUES (7844,'TURNER','SALESMAN',7698,'1981-9-8',1500,0,30);
INSERT INTO emp VALUES (7876,'ADAMS','CLERK',7788,'1987-7-13',1100,NULL,20);
INSERT INTO emp VALUES (7900,'JAMES','CLERK',7698,'1981-12-3',950,NULL,30);
INSERT INTO emp VALUES (7902,'FORD','ANALYST',7566,'1981-12-3',3000,NULL,20);
INSERT INTO emp VALUES (7934,'MILLER','CLERK',7782,'1982-1-23',1300,NULL,10);
select empno,ename,job,deptno,sal,row_number() over(partition by deptno order by sal desc) Rn from emp;