学习计划:
1.pl/sql 基本的语法格式
2.记录类型 type ... is record(,,,,);
3.流程控制
3.1 条件判断(两种)
方式一:if .... then elsif then ... else ... end if;
方式二:case ... when ... then ... end;
3.2 循环结构(三种)
方式一:loop ... exit when ... end loop;
方式二:while ... loop ... end loop;
方式三:for i in ... loop ... end loop;
3.3 goto,exit
4.游标的使用(类似java中Iterator)
5.异常的处理(三种方式)
6.存储函数(有返回值)function,存储过程(没有返回值)procedure
7.触发器 trigger
8.set serveroutput on数据设置。
语法:
declare
-- 变量 ,记录类型等的声明
begin
-- 程序的执行部分
exception
-- 异常的处理
end;
实例1:
declare
--声明一个记录类型
type emp_record is record(
v_sal employees.salary%type,
v_email employees.email%type,
v_hire_date employees.hire_date%type
);
--定义一个记录类型的成员变量
v_emp_record emp_record;
begin
select salary,email,hire_date into v_emp_record from employees where employee_id = 100;
dbms_output.put_line(v_emp_record.v_sal||','||v_emp_record.v_email||','||v_emp_record.v_hire_date);
end;
实例2
declare
-- 变量 ,记录类型等的声明
v_sal number(8,2) := 0;
v_emp_id number(10);
v_email varchar2(20);
v_hire_date date;
begin
-- 程序的执行部分
select salary,employee_id,email,hire_date into v_sal,v_emp_id,v_email,v_hire_date from employees where employee_id = 123;
dbms_output.put_line('员工编号:'||v_emp_id||'工资:'||v_sal||'邮箱:'||v_email||'入职时间:'||v_hire_date);
-- exception
-- 异常的处理
end;
实例3:用记录类型升级
declare
-- 变量 ,记录类型等的声明
type emp_record is record(
v_sal number(8,2) := 0,
v_emp_id number(10),
v_email varchar2(20),
v_hire_date date
);
v_emp_red emp_record;
begin
-- 程序的执行部分
select salary,employee_id,email,hire_date into v_emp_red from employees where employee_id = 123;
dbms_output.put_line('员工编号:'||v_emp_red.v_emp_id||'工资:'||v_emp_red.v_sal||'邮箱:'||v_emp_red.v_email||'入职时间:'||v_emp_red.v_hire_date);
-- exception
-- 异常的处理
end;
实例4:
declare
type salary_record is record(
v_name varchar2(20),
v_salary number(10,2)
);
v_sal_record salary_record;
begin
v_sal_record.v_name := '刘德华';
v_sal_record.v_salary := 120000;
dbms_output.put_line('姓名:'||v_sal_record.v_name||'薪资:'||v_sal_record.v_salary);
end;
实例5:
declare
-- 变量 ,记录类型等的声明
/*
type emp_record is record(
v_sal number(8,2) := 0,
v_emp_id number(10),
v_email varchar2(20),
v_hire_date date
);
v_emp_red emp_record;
*/
v_emp_record employees%rowtype;
begin
-- 程序的执行部分
-- select salary,employee_id,email,hire_date into v_emp_red from employees where employee_id = 123;
select * into v_emp_record from employees where employee_id = 123;
dbms_output.put_line('员工编号:'||v_emp_record.employee_id||'工资:'||v_emp_record.salary||'邮箱:'||v_emp_record.email||'入职时间:'||v_emp_record.hire_date);
-- exception
-- 异常的处理
end;
实例6:
declare
v_emp_id number(10);
begin
v_emp_id := 123;
update employees set salary = salary+100 where employee_id = v_emp_id;
dbms_output.put_line('执行成功!');
end;
实例7:流程控制语句
declare
v_sal employees.salary%type;
begin
select salary into v_sal from employees where employee_id = 150;
if v_sal >= 10000 then dbms_output.put_line('salary>10000');
elsif v_sal >= 5000 then dbms_output.put_line('5000<salary<10000');
else dbms_output.put_line('salary<5000');
end if;
end;
升级版:
declare
v_sal employees.salary%type;
v_temp varchar2(50);
begin
select salary into v_sal from employees where employee_id = 150;
if v_sal >= 10000 then v_temp := 'salary>10000';
elsif v_sal >= 5000 then v_temp := '5000<salary<10000';
else v_temp :='salary<5000';
end if;
dbms_output.put_line(v_temp);
end;
实例7:case when ... then
declare
v_sal employees.salary%type;
v_temp varchar2(50);
begin
select salary into v_sal from employees where employee_id = 150;
v_temp := case trunc(v_sal/5000) when 0 then 'salary<5000'
when 1 then '5000<salary<10000'
else 'salary>10000'
end;
dbms_output.put_line(v_temp);
end;
实例8:
declare
v_job_id employees.job_id%type;
v_temp varchar2(10);
begin
select job_id into v_job_id from employees where employee_id = 122;
v_temp :=
case v_job_id when 'IT_PROG' then 'A'
when 'AC_MGT' then 'B'
when 'AC_ACCOUNT' then 'C'
ELSE 'D'
end;
dbms_output.put_line(v_job_id||','||v_temp);
end;
实例9:
declare
--初始化条件 循环体 循环条件 迭代条件
--声明变量
v_i number(5) := 1;
begin
loop
--循环体
dbms_output.put_line(v_i);
--迭代条件
v_i := v_i +1;
--循环条件
exit when v_i > 100;
end loop;
end;
实例10:
declare
v_i number(5) := 1;
begin
while v_i <= 100 loop
dbms_output.put_line(v_i);
v_i := v_i + 1;
end loop;
end;
实例11:
declare
v_s number(5) := 1;
v_e number(5) := 100;
begin
for c in v_s..v_e loop
dbms_output.put_line(c);
end loop;
end;
declare
v_s number(5) := 1;
v_e number(5) := 100;
begin
for c in reverse v_s..v_e loop
dbms_output.put_line(c);
end loop;
end;
实例12:
--输出2-100之间的质数
declare
v_i number(3) := 2;
v_j number(3) := 2;
v_flag number(1) := 1;
begin
while v_i <= 100 loop
while v_j <= sqrt(v_i) loop
if mod(v_i,v_j) = 0 then v_flag := 0;
end if;
v_j := v_j + 1;
end loop;
if v_flag = 1 then dbms_output.put_line(v_i);
end if;
v_j := 2;
v_i := v_i + 1;
v_flag := 1;
end loop;
end;
实例13:
--输出2-100之间的质数
declare
v_flag number(1) := 1;
begin
for v_i in 2..100 loop
for v_j in 2..sqrt(v_i) loop
if mod(v_i,v_j) = 0 then v_flag := 0;
end if;
end loop;
if v_flag = 1 then dbms_output.put_line(v_i);
end if; v_flag := 1;
end loop;
end;
升级版:
--输出2-100之间的质数
declare
v_flag number(1) := 1;
begin
for v_i in 2..100 loop
for v_j in 2..sqrt(v_i) loop
if mod(v_i,v_j) = 0 then v_flag := 0;
goto label;
end if;
end loop;
<<label>>
if v_flag = 1 then dbms_output.put_line(v_i);
end if;
v_flag := 1;
end loop;
end;
begin
for i in 1..100 loop
if i = 50 then goto label;
end if;
dbms_output.put_line(i);
end loop;
<<label>>
dbms_output.put_line('打印结束');
end;
游标:
declare
v_sal employees.salary%type;
v_emp_id employees.employee_id%type;
--定义游标
cursor emp_sal_cursor is select salary,employee_id from employees where department_id = 80;
begin
--打开游标
open emp_sal_cursor;
--提取游标
fetch emp_sal_cursor into v_sal,v_emp_id;
while emp_sal_cursor%found loop
dbms_output.put_line('员工号:'||v_emp_id||'的工资:'||v_sal);
fetch emp_sal_cursor into v_sal,v_emp_id;
end loop;
--关闭游标
close emp_sal_cursor;
end;
for游标:
declare
-- v_sal employees.salary%type;
-- v_emp_id employees.employee_id%type;
--定义游标
cursor emp_sal_cursor is select salary,employee_id from employees where department_id = 80;
begin
/*
--打开游标
open emp_sal_cursor;
--提取游标
fetch emp_sal_cursor into v_sal,v_emp_id;
while emp_sal_cursor%found loop
dbms_output.put_line('员工号:'||v_emp_id||'的工资:'||v_sal);
fetch emp_sal_cursor into v_sal,v_emp_id;
end loop;
--关闭游标
close emp_sal_cursor;
*/
for c in emp_sal_cursor loop
dbms_output.put_line('员工号:'||c.employee_id||'的工资:'||c.salary);
end loop;
end;
实例:set
select employee_id,department_id from emp_01
union
select employee_id,department_id from emp_02
select employee_id,department_id from emp_01
union all
select employee_id,department_id from emp_02
select employee_id emp_id,department_id dept_id from emp_01
intersect
select employee_id,department_id from emp_02
order by emp_id desc
select employee_id emp_id,department_id dept_id,to_char(null) from emp_01
minus
select to_number(null),department_id,department_name from departments
select employee_id emp_id,department_id dept_id,to_char(null) from emp_01
union all
select to_number(null),department_id,department_name from departments
/*select department_id
from departments
where department_id not in (
select DISTINCT department_id from employees where job_id = 'ST_CLERK'
)*/
SELECT department_id from departments
minus
select department_id
from employees
where job_id = 'ST_CLERK'
column a_dummy noprint;
select job_id,department_id,1 a_dummy from employees
where department_id = 10
union
select job_id,department_id,2 from employees
where department_id = 50
union
select job_id,department_id,3 from employees
where department_id = 20
order by 3 asc
select last_name,department_id,to_char(null)
from employees
union
select to_char(null),department_id,department_name
from departments
--查询last_name为Chen的manager的信息
select employee_id,last_name
from employees
where employee_id=(select manager_id
from employees
where last_name = 'Chen')
多列子查询:
select employee_id,manager_id,department_id from
employees
where (manager_id,department_id) in (select manager_id,department_id from employees
where employee_id in (141,174))
select employee_id,manager_id,department_id from
employees where manager_id in (select manager_id from employees
where employee_id in (141,174))
and department_id in (select department_id from employees
where employee_id in (141,174))
--计算比本部门平均工资高的员工的信息
select last_name,department_id,salary,(select avg(salary) from employees e3 where e1.department_id = e3.department_id group by department_id) avgsal
from employees e1 where salary > (
select avg(salary)
from employees e2
where e1.department_id = e2.department_id )
--计算比本部门平均工资高的员工的信息
select last_name,e1.department_id,e1.salary,e2.salaravg
from employees e1,(select department_id,avg(salary) salaravg from employees group by department_id) e2
where e1.department_id = e2.department_id and salary>e2.salaravg
select employee_id,last_name,(case department_id
when (select department_id from departments
where location_id = 1800) then 'Canada'
else 'USA' end)location
from employees
select employee_id,last_name
from employees emp
order by (select department_name
from departments dept
where emp.department_id = dept.department_id
) asc
select employee_id,last_name,job_id
from employees emp
where 2<= (
select count(*) from job_history
where employee_id = emp.employee_id
)
-- 查询公司管理者的employee_id,last_name,job_id,department_id信息
select employee_id,last_name,job_id,department_id
from employees emp
where emp.employee_id in (
select manager_id
from employees mana
where emp.employee_id = mana.manager_id
)
-- 查询公司管理者的employee_id,last_name,job_id,department_id信息
select distinct emp.employee_id,emp.last_name,emp.job_id,emp.department_id
from employees emp,employees mana
where emp.employee_id = mana.manager_id
-- 查询公司管理者的employee_id,last_name,job_id,department_id信息
select emp.employee_id,emp.last_name,emp.job_id,emp.department_id
from employees emp
where exists (
select 'A' from employees mana
where emp.employee_id = mana.manager_id
)
--查询departments表中,不存在与employees表中的部门的department_id和department_name
select department_id,department_name
from departments dept
where not exists(
select 'c' from employees
where department_id = dept.department_id
)
--查询departments表中,不存在与employees表中的部门的department_id和department_name
select department_id
from departments dept
minus
select department_id
from employees
--查询公司中工资比Abel高的员工的工资
/*select employee_id,salary
from employees
where salary > (
select salary from employees
where last_name = 'Abel'
)*/
with Abel_sal as (
select salary from employees
where last_name = 'Abel'
)
select employee_id,salary
from employees
where salary > (
select salary from Abel_sal
)
--查询公司中各部门的总工资大于公司中各部门的平均总工资的部门信息
with dept_sum_sal as (
select department_name,sum(salary) sum_sal
from employees e,departments d
where e.department_id = d.department_id
group by department_name),
dept_avg_sal as (
select sum(sum_sal)/count(*) avg_sal from dept_sum_sal
)
select *
from dept_sum_sal
where sum_sal > (
select avg_sal
from dept_avg_sal
)
order by department_name
--1. 查询员工的last_name, department_id, salary.其中员工的salary,department_id
--与有奖金的任何一个员工的salary,department_id相同即可
select last_name,department_id,salary
from employees
where (salary,department_id) in (
select salary,department_id
from employees
where commission_pct is not null
)
--2. 选择工资大于所有JOB_ID = 'SA_MAN'的员工的工资的员工的last_name, job_id, salary
select last_name,job_id,salary
from employees
where salary > all(
select salary from
employees
where job_id = 'SA_MAN'
)
--3. 选择所有没有管理者的员工的last_name
/*
select last_name
from employees
where manager_id is null
*/
select last_name
from employees emp
where not exists (
select 'c' from employees
where employee_id = emp.manager_id
)