學習計劃:
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
)