Oacle 복습 노트 의 PL/SQL 프로그램 이 알 아야 할 지식

21412 단어 OaclePL/SQL
복습 내용:
PL/SQL 의 기본 문법,기록 유형,절차 제어,커서 사용,
이상 처리 메커니즘,저장 함수/저장 과정,트리거.
여러분 이 제 노트 에 따라 연습 하 는 것 을 편리 하 게 하기 위해 데이터베이스 시트 파일 을 제공 합 니 다주문 하 다
출력 결 과 를 얻 기 위해 서 는 PL/SQL 프로그램 을 쓰기 전에 이 문장 을 먼저 실행 합 니 다.
set serveroutput on
구조:
declare
--성명 변수,유형,커서
begin
--프로그램의 실행 부분(자바 의 main()방법 과 유사)
exception
--begin 블록 에서 나타 나 는 이상 에 대해 처리 메커니즘 을 제공한다
--when...then...
--when...then...
end;
예 1:

declare
  v_sal number(10); (             , java    )
begin
  select salary into v_sal from employees where employee_id = 100;
  dbms_output.put_line(v_sal);
end;
예 2:

declare
  v_sal number(10); (  ,                 )
  v_email varchar2(20);
  v_hire_date date;
begin
  select salary,email,hire_date into v_sal,v_email,v_hire_date from employees where employee_id = 
100;
  dbms_output.put_line(v_sal||','||v_email||','||v_hire_date);
end;
  :
declare
  v_sal employees.salary%type;
  v_email employees.email%type;
  v_hire_date employees.hire_date%type;
begin
  select salary,email,hire_date into v_sal,v_email,v_hire_date from employees where employee_id = 
100;
  dbms_output.put_line(v_sal||','||v_email||','||v_hire_date);
end;
기록:

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;
1.pl/sql 기본 문법 형식
2.기록 형식 type...is...record(,,);
3.절차 제어:
3.1 조건 판단(두 가지)
방식 1:if...then elseif then...else...end if;
방식 2:case...when...then...end;
3.2 순환 구조(세 가지)
방식 1:loop...exit when...end loop;
방식 2:while...loop...end loop;
방식 3:for i in...loop...end loop;
3.3 goto、exit
4.커서 사용(자바 의 Iterator 와 유사)
5.이상 처리
6.메모리 함수(반환 값 있 음),메모리 프로 세 스(반환 값 없 음)를 작성 합 니 다.
7.트리거 를 쓴다
복습 기록 유형:

declare
type emp_record is record(
  -- v_emp_id employees.employee_id%type,
  -- v_sal employees.salary%type
  v_emp_id number(10) := 120,
  v_sal number(10,2) :=12000
);
  v_emp_record emp_record;
begin
  -- select employee_id,salary into v_emp_record from employees where employee_id = 123;
  dbms_output.put_line('employee_id:'||v_emp_record.v_emp_id||' '||'salary:'|| 
  v_emp_record.v_sal);
end;
업그레이드 도 할 수 있 습 니 다.표 의 모든 열 을 출력 하려 면:(출력 된 열 이름 은 표 의 열 이름과 같 아야 합 니 다)

declare
  v_emp_record employees%rowtype;
begin
  select * into v_emp_record from employees where employee_id = 123;
  dbms_output.put_line('employee_id:'||v_emp_record.employee_id||' '||'salary:'|| 
  v_emp_record.salary);
end;
       update  :
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;
흐름 제어:
150 번 직원 의 월급 을 조회 하고 월급 이 10000 보다 많 거나 같 으 면'salary>=10000'을 인쇄 합 니 다.
5000 에서 10000 사이 에 있 으 면'5000<=salary<10000'을 인쇄 합 니 다.그렇지 않 으 면'salary<5000'을 인쇄 합 니 다.

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('10000 > salary >= 5000');
  else dbms_output.put_line('salary < 5000');
  end if;
  dbms_output.put_line('salary:'||v_sal);
end;
  case ... when ... then ... when ...then ... else ... end    ;
declare 
  v_sal employees.salary%type;
  v_temp varchar2(20);
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('salary:'||v_sal||' '||v_temp);
end;
122 번 직원 의 job 조회id,만약 그 값 이'IT'라면PROG'는'GRADE:A'를 출력 합 니 다.
                                                ‘AC_MGT'는'GRADE:B'를 인쇄 합 니 다.
                                                ‘AC_ACCOUNT'는'GRADE:B'를 출력 합 니 다.
                                                 그렇지 않 으 면'GRADE:D'를 인쇄 합 니 다.

declare 
  v_job_id employees.job_id%type;
  v_temp varchar2(20);
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('job_id:'||v_job_id||' '||v_temp);
end;
순환 문 인쇄 사용:1-100

declare
  v_i number(5) :=1;

begin
  loop
  dbms_output.put_line(v_i);
  exit when v_i >=100;
  v_i := v_i + 1;
  end loop;
end;
  while  :
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;
  for...in...loop...end loop;  :
begin
  for c in 1..100 loop
   dbms_output.put_line(c);
  end loop;
end;

출력 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;
for 순환 을 이용 하여 출력 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; 
goto 로 개선 할 수 있 습 니 다:

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; 
1-100 의 자연 수 를 인쇄 합 니 다.50 까지 인쇄 할 때 순환 을 뛰 어 내 려'인쇄 끝'을 출력 합 니 다.

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;
  :
begin 
  for i in 1..100 loop
   if i=50 then dbms_output.put_line('    ');
   exit;
   end if;
  dbms_output.put_line(i);
  end loop;
end;
 
커서:
80 부서 의 모든 직원 의 월급 을 출력 합 니 다:salary:XXX
declare
v_sal employees.salary%type;
--커서 정의
cursor emp_sal_cursor is select salary from employees where department_id = 80;
begin
--커서 열기
open emp_sal_cursor;
--커서 추출
fetch emp_sal_cursor into v_sal;
while emp_sal_cursor%found loop
dbms_output.put_line('salary:'||v_sal);
fetch emp_sal_cursor into v_sal;
end loop;
--커서 닫 기
close emp_sal_cursor;
end;
다음 과 같이 최적화 할 수 있 습 니 다.

declare
v_empid employees.employee_id%type;
v_lastName employees.last_name%type;
v_sal employees.salary%type;
cursor emp_sal_cursor is select employee_id,last_name,salary from employees where 
department_id = 80;
begin 
open emp_sal_cursor;
fetch emp_sal_cursor into v_empid,v_lastName,v_sal;
while emp_sal_cursor%found loop
dbms_output.put_line('employee_id:'||v_empid||', '||'last_name:'||v_lastName||', 
'||'salary:'||v_sal);
fetch emp_sal_cursor into v_empid,v_lastName,v_sal;
end loop;
close emp_sal_cursor;
end;
또는 기록 을 사용 하여 최적화:

declare
type emp_record is record(
v_empid employees.employee_id%type,
v_lastName employees.last_name%type,
v_sal employees.salary%type
);
v_emp_record emp_record;
cursor emp_sal_cursor is select employee_id,last_name,salary from employees where 
department_id = 80;
begin 
open emp_sal_cursor;
fetch emp_sal_cursor into v_emp_record;
while emp_sal_cursor%found loop
dbms_output.put_line('employee_id:'||v_emp_record.v_empid||', '||'last_name:'|| 
v_emp_record.v_lastName||', '||'salary:'||v_emp_record.v_sal);
fetch emp_sal_cursor into v_emp_record;
end loop;
close emp_sal_cursor;
end; 
for 순환 을 사용 하여 최적화 할 수 있 습 니 다.(주의:for 순환 에서 커서 를 자동 으로 열 고 커서 를 추출 합 니 다.안의 데 이 터 를 추출 한 후에 도 자동 으로 됩 니 다.
커서 닫 기

declare
cursor emp_sal_cursor is select employee_id,last_name,salary from employees where 
department_id = 80;
begin 
for c in emp_sal_cursor loop
dbms_output.put_line('employee_id:'||c.employee_id||', '||'last_name:'||c.last_name||', 
'||'salary:'||c.salary);
end loop;
end;
커서 를 이용 하여 회사 직원 들 의 월급 을 조정 합 니 다.
임금 범위           조정 기수
0 - 5000              5%
5000 - 10000       3%
10000 - 15000     2%
15000 -               1%
실현:

declare 
  cursor emp_cursor is select employee_id,salary from employees;
  v_empid employees.employee_id%type;
  v_sal employees.salary%type;
  v_temp number(4,2);
begin 
  open emp_cursor;
  fetch emp_cursor into v_empid,v_sal;
  while emp_cursor%found loop
   if v_sal < 5000 then v_temp:=0.05;
   elsif v_sal < 10000 then v_temp:=0.03;
   elsif v_sal < 15000 then v_temp:=0.02;
   else v_temp:=0.01;
   end if;
  dbms_output.put_line(v_empid||','||v_sal);
  update employees
  set salary = salary * (1+v_temp)
  where employee_id = v_empid;
  fetch emp_cursor into v_empid,v_sal;
  end loop;
  close emp_cursor;
end;
for 순환 으로 구현

declare 
  cursor emp_cursor is select employee_id,salary from employees;
  v_temp number(4,2); 
begin 
  for c in emp_cursor loop
   if c.salary <5000 then v_temp:=0.05;
   elsif c.salary <10000 then v_temp:=0.03;
   elsif c.salary <15000 then v_temp:=0.02;
   else v_temp:=0.01;
  end if;
  update employees
  set salary = salary * (1+v_temp)
  where employee_id = c.employee_id;
  end loop;
end;
암시 적 커서:직원 샐 러 리(임금 인상 10)를 업데이트 하고 이 직원 이 찾 지 못 하면'이 사람 이 없 음'정 보 를 인쇄 합 니 다.

begin 
  update employees
  set salary = salary + 10
  where employee_id = 1001;
   if sql%notfound then dbms_output.put_line('    ');
   end if;
end;
이상:
미리 정 의 된 이상:(24 개의 미리 정 의 된 이상,검사 가능 표)

declare
  v_sal employees.salary%type;
begin 
  select salary into v_sal from employees 
  where employee_id > 100;
  dbms_output.put_line(v_sal); 
exception
  when too_many_rows then dbms_output.put_line('       ');
  when others then dbms_output.put_line('        ');
end;
미리 정의 되 지 않 은 이상:

declare
  e_deleteid_exception exception;
  pragma exception_init(e_deleteid_exception,-2292);
begin 
  delete from employees
  where employee_id = 100; 
exception
  when e_deleteid_exception then dbms_output.put_line('        ,        ');
  when others then dbms_output.put_line('        ');
end;
사용자 정의 이상:

declare
  e_sal_hight exception;
  v_sal employees.salary%type;
begin 
  select salary into v_sal from employees where employee_id = 100;
  if v_sal > 10000 then raise e_sal_hight;
  end if;
exception
  when e_sal_hight then dbms_output.put_line('     ');
  when others then dbms_output.put_line('        ');
end;
select...into...누군가의 월급 을 조회 하고 찾 지 못 하면'이 데 이 터 를 찾 지 못 했 습 니 다'를 출력 합 니 다.

declare
  v_sal employees.salary%type;
begin 
  select salary into v_sal from employees where employee_id = 1001;
exception
  when no_data_found then dbms_output.put_line('      ');
  when others then dbms_output.put_line('        ');
end;
        ,     300,  100, NO_DATA_FOUND  ,TOO_MANY_ROWS    。
declare
  v_sal employees.salary%type;
begin 
  select salary into v_sal from employees where employee_id = 1001;
  if v_sal < 300 then update employees set salary = salary + 100 where employee_id =101;
  end if;
exception
  when no_data_found then dbms_output.put_line('      ');
  when too_many_rows then dbms_output.put_line('        ');
  when others then dbms_output.put_line('        ');
end;
사용자 정의 이상:
지 정 된 직원 의 임금 을 갱신 하고 100 증가 합 니 다.지정 한 직원 이 없 으 면 이상 던 지기:NORESULT;

declare 
  no_result exception;
begin 
  update employees set salary = salary + 100 where employee_id = 1001;
  if sql%notfound then raise no_result;
  end if;
exception 
  when no_result then dbms_output.put_line('     ,    '); 
  when others then dbms_output.put_line('      '); 
end;
저장 프로시저:
간단 한 helloworld 메모리 함수

create or replace function hello_world 
return varchar2
is (   declare,          、  、  )
begin 
  return 'helloworld';
end;
       :
begin 
  dbms_output.put_line(hello_world);
end;
  :
select hello_world from dual;
매개 변수 가 있 는 저장 함수:

create or replace function hello_world1(v_logo varchar2)
return varchar2
is 
begin 
  return 'helloworld'||v_logo;
end;
  :
select hello_world1('shellway') from dual
  :
begin 
  dbms_output.put_line(hello_world1('shellway'));
end;
시스템 시간 을 가 져 오 는 함 수 를 정의 합 니 다:

create or replace function get_sysdate
return varchar2
is 
begin 
  return to_char(sysdate,'yyyy-MM-dd HH24:mi:ss');
end;
매개 변수 가 있 는 함 수 를 정의 하고 두 수 를 더 합 니 다.

create or replace function add_param(v_num1 number,v_num2 number)
return number
is
  v_num3 number(10);
begin
  v_num3 := v_num1 + v_num2;
  return v_num3;
end;
  :
select add_param(2,5) from dual;
  :
begin 
  dbms_output.put_line(add_param(5,4));
end; 
함수 정의:주어진 부서 의 임금 총 계 를 가 져 옵 니 다.요구:부서 번 호 는 매개 변수 로 정의 되 고 임금 총액 은 반환 값 입 니 다.

create or replace function get_sal(dept_id number)
return number
is 
  v_sumsal number(10) := 0;
  cursor salary_cursor is select salary from employees where department_id = dept_id;
begin 
  for c in salary_cursor loop 
  v_sumsal := v_sumsal + c.salary;
  end loop;
  return v_sumsal;
end;
  :
select get_sal(80) from dual;
함수 정의:주어진 부서 의 임금 총액 과 해당 부서 의 직원 총수(OUT 유형의 매개 변수 로 정의)를 가 져 옵 니 다.
요구:부서 번 호 는 매개 변수 로 정의 되 고 임금 총액 은 반환 값 으로 정의 된다.

create or replace function get_sal(dept_id number,total_count out number)
return number
is 
 v_sumsal number(10) := 0;
 cursor salary_cursor is select salary from employees where department_id = dept_id;
begin 
  total_count := 0;
  for c in salary_cursor loop 
    v_sumsal := v_sumsal + c.salary;
    total_count := total_count + 1;
  end loop;
  return v_sumsal;
end;
  :
declare
  v_count number(4);
begin 
  dbms_output.put_line(get_sal(80,v_count));
  dbms_output.put_line(v_count);
end;
저장 프로 세 스 정의:주어진 부서 의 임금 총화(out 매개 변 수 를 통 해)를 얻 고 부서 번호 와 임금 총액 을 매개 변수 로 정의 하도록 요구 합 니 다.
(메모:저장 과정 과 저장 함 수 는 다 릅 니 다.저장 함 수 는 반환 값 이 있 고 저장 과정 이 없습니다.호출 할 때 저장 과정 은 직접 호출 됩 니 다)

create or replace procedure get_sal1(dept_id number,sumsal out number)
is 
 cursor salary_cursor is select salary from employees where department_id = dept_id;
begin 
 sumsal := 0;
 for c in salary_cursor loop 
   sumsal := sumsal + c.salary;
 end loop;
 dbms_output.put_line(sumsal);
end;
  :
declare 
  v_sal number(10):=0; 
begin 
 get_sal1(80,v_sal);
end;
주어진 부서(입력 매개 변수 로)의 직원 에 게 임금 인상 작업 을 하고 회사 에 도착 하 는 시간 이(??95)기간 동안 5%의 임금 인상
                                                                                          (95,98)                  3%
                                                                                          (98,?)                   1%
다음 과 같은 반환 결 과 를 얻 었 습 니 다.이번 임금 인상 회 사 를 위해 매달 몇 할 을 추가 로 지불 합 니까?(OUT 형의 출력 매개 변 수 를 정의 합 니 다)

create or replace procedure add_sal(dept_id number,temp out number)
is
  cursor sal_cursor is select employee_id,salary,hire_date 
  from employees where department_id = dept_id;
  v_temp number(4,2):=0;
begin 
  temp := 0;
  for c in sal_cursor loop
    if to_char(c.hire_date,'yyyy') < '1995' then v_temp:=0.05;
    elsif to_char(c.hire_date,'yyyy') < '1998' then v_temp:=0.03;
    else v_temp:=0.01;
    end if;

  update employees 
  set salary = salary * (1+v_temp) 
  where employee_id = c.employee_id;

  temp := temp + c.salary*v_temp; 
  end loop;
  dbms_output.put_line(temp);
end;
  :
declare 
  v_i number(10):=0;
begin
  add_sal(80,v_i);
end;

트리거:
트리거 이벤트:INSERT,UPDATE,DELETE 의 경우 TRIGGER 를 터치 합 니 다.
트리거 시간:이 TRIGGER 는 트리거 이벤트 가 발생 하기 전(BEFORE)또는 그 후(AFTER)
트리거 자체:이 TRIGGER 가 실 행 된 후의 목적 과 의 도 는 바로 트리거 자체 가 해 야 할 일 입 니 다.예 를 들 어 PL/SQL 블록 등 입 니 다.
트리거 주파수:구문 급(STATEMENT)트리거 와 행 급(ROW)트리거
간단 한 트리거 쓰기:

create or replace trigger update_emp_trigger
after
  update on employees
for each row (     ,              'helloworld',              )
begin
  dbms_output.put_line('helloworld');
end;
사용:new,:old 장식 부호:

1、
create table emp1
as
select employee_id,salary,email from employees where department_id = 80;
2、
create or replace trigger update_emp_trigger2
after
  update on emp1
for each row
begin
  dbms_output.put_line('old salary:'||:old.salary||'new salary:'||:new.salary);
end;
3、
update emp1 set salary = salary + 100 ;
트리거 를 작성 하여 myemp 기록 을 삭제 할 때 myemp_bak 표 에 대응 하 는 기록 을 백업 합 니 다.

1、  my_emp :
create table my_emp 
as
select employee_id,salary from employees ;
2、  my_emp_bak :
create table my_emp_bak
as
select employee_id,salary from employees where 1=2;
3、          :
select * from my_emp
select * from my_emp_bak
4、       :
create or replace trigger delete_emp_trigger 
before
  delete on my_emp 
for each row
begin
  insert into my_emp_bak 
  values(:old.employee_id,:old.salary);
end;
5、            :
delete from my_emp
6、           :
select * from my_emp
select * from my_emp_bak

좋은 웹페이지 즐겨찾기