Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | ||||
4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 | 26 | 27 | 28 | 29 | 30 | 31 |
Tags
- 페이징
- 별찍기
- 인코딩
- 정처기
- 검색기능
- github
- emmet환경설정
- 회원정보수정
- 배열
- 회원탈퇴
- live server 환경설정
- 국취제
- 페이지 재사용
- jsp기본
- forward
- Git
- 권한변경
- jdbc환경설정
- 내일배움카드
- mvc
- redirect
- 국민취업지원제도
- jdbc설정
- 입력메소드
- 비밀번호암호화
- 국비학원
- 내배카
- 관리자회원조회
- 로그아웃
- 비밀번호변경
Archives
- Today
- Total
기록
*44일차(DATABASE OBJECT2 / cursor) 본문
@DATABASE OBJECT2
- pl/sql문법을 사용하는 db객체 (function, procedure, cursor, trigger, . . . .)
*STORED FUNCTION
- 리턴값이 반드시 존재하는 프로시저 객체
- 함수객체는 일반 sql, 다른 프로시저, 익명블럭에서 호출이 가능
- 기존 sql 실행과 달리 미리 컴파일 하므로 실행속도 빠름
/*
create [or replace] function 함수명(매개변수1, 매개변수2, ...)
return 자료형
is
-- 지역변수선언
begin
-- 실행코드
return 리턴값;
exception
-- 예외처리
return 예외발생시 리턴값;
end;
/
*/
--양모자씌우기
--매개변수, 리턴타입도 자료크기는 지정하지 않는다.
--pl,sql의 varchar2(32676 byte)가 최대
create or replace function myfunc(p_emp_name employee.emp_name%type)
return varchar2
is
result varchar2(32676);
begin
result := 'd' || p_emp_name || 'b';
dbms_output.put_line(result || '@myfunc');
return result;
end;
/
--익명블럭에서 호출
--일반 sql문에서 호출
--함수내부의 로그출력 없음
begin
dbms_output.put_line(myfunc('&이름'));
end;
/
select
myfunc(emp_name)
from
employee;
--data_dictionary에서 확인
--user_procedure에서 object_type = 'FUNCTION'
select
*
from
user_procedures
where
object_type = 'FUNCTION';
--주민번호를 인자로 성별을 리턴하는 저장함수 fn_get_gender
create or replace function fn_get_gender(
p_emp_no employee.emp_no%type
)
return char
is
v_gender char(3);
begin
case substr(p_emp_no, 8, 1)
when '1' then v_gender := '남';
when '3' then v_gender := '남';
else v_gender := '여';
end case;
return v_gender;
end;
/
select
emp_name,
emp_no,
fn_get_gender(emp_no) gender
from
employee;
--주민번호를 인자로 받아서 한국나이를 리턴하는 fn_get_age
-- 현재년도- 출생년도 +1
create or replace function fn_get_age(
p_emp_no employee.emp_no%type
)
return number
is
sys_year number := extract(year from sysdate);
birth_year number;
begin
-- 출생년도
case
when substr(p_emp_no, 8, 1) in ('1', '2')
then birth_year := 1900 + substr(p_emp_no, 1, 2);
else
birth_year := 2000 + substr(p_emp_no, 1, 2);
end case;
-- 나이 리턴
return sys_year - birth_year + 1;
end;
/
select
emp_name,
fn_get_age(emp_no) age
from
employee;
*STORED PROCEDURE
- 일련의 작업절차를 객체로 저장하고 호출해서 사용하는 객체
- 리턴값이 없다
- out 매개변수를 이용해 호출부로 값전달 가능
- 미리 컴파일 해두므로 일반 sql대비 처리효율이 좋다
- select문에서 호출불가
- 익명블럭 or 다른 프로시저에서 호출가능
/*
create [or replace] procedure 프로시져명(매개변수1 mode 자료형, 매개변수2 mode 자료형, ...)
is
-- 지역변수 선언
begin
-- 실행코드
end;
/
mode : in | out | inout
- in 프로시져 값을 전달(기본값)
- out 프로시져의 처리내용을 담아서 호출부로 전달
- inout
*/
create or replace procedure proc_get_emp(
p_emp_id in employee.emp_id%type,
p_emp_name out employee.emp_name%type,
p_phone out employee.phone%type
)
is
begin
-- 해당사원조회
select
emp_name, phone
into
p_emp_name, p_phone
from
employee
where
emp_id = p_emp_id;
dbms_output.put_line('사원명@proc_get_emp : ' || p_emp_name);
dbms_output.put_line('전화번호@proc_get_emp : ' || p_phone);
end;
/
--익명블럭에서 호출
declare
v_emp_id employee.emp_id%type := '&사번';
v_emp_name employee.emp_name%type;
v_phone employee.phone%type;
begin
-- 프로시져호출
proc_get_emp(v_emp_id, v_emp_name, v_phone);
-- 값 확인
dbms_output.put_line('사원명 : ' || v_emp_name);
dbms_output.put_line('전화번호 : ' || v_phone);
end;
/
--사원삭제 프로시저
--DML처리시 트랜잭션 처리까지 함께 할것
create or replace procedure proc_del_emp(
p_emp_id ex_employee.emp_id%type -- in mode(기본값)
)
is
begin
-- 삭제
delete from
ex_employee
where
emp_id = p_emp_id;
-- 트랜잭션처리
commit;
-- 콘솔로깅
dbms_output.put_line(p_emp_id || '번 사원을 삭제했습니다.');
end;
/
select * from ex_employee;
begin
proc_del_emp('&사번');
end;
/
select * from ex_employee;
begin
proc_del_emp('&사번');
end;
/
--upsert 예제
--특정행 없으면 insert
--특정행 있으면 update
-- ex_job테이블
create table ex_job
as
select * from job;
-- 기본키, 자료형 수정
alter table
ex_job
add constraint pk_ex_job_code primary key(job_code)
modify job_code varchar2(5)
modify job_name not null;
--인자로 전달한 직급코드,직급명에 따라 insert or update처리하는 프로시저
create or replace procedure proc_upsert_ex_job(
p_job_code ex_job.job_code%type,
p_job_name ex_job.job_name%type
)
is
v_cnt number;
begin
-- 1.p_job_code가 존재하는지 여부
select
count(*)
into
v_cnt
from
ex_job
where
job_code = p_job_code;
-- 2.존재하면 update, 존재하지 않으면 insert
if v_cnt = 0 then
insert into
ex_job
values (
p_job_code, p_job_name
);
else
update
ex_job
set
job_name = p_job_name
where
job_code = p_job_code;
end if;
-- 3.트랜잭션처리
commit;
end;
/
begin
-- proc_upsert_ex_job('J8', '인턴'); -- insert
proc_upsert_ex_job('J8', '수습'); -- update
end;
/
select * from ex_job;
-- dd에서 조회
select * from user_procedures where object_type = 'PROCEDURE';
@CURSOR
- 커서란 sql실행결과를 갖고있는 메모리영역(private sql)에 대한 포인터객체
- 한 행이상의 결과집합인 경우도 순차적으로 접근가능
- open ~ fetch ~ close의 단계를 거쳐 처리하게 된다.
- 암시적 커서
- 명시적 커서
*커서 속성
- %rowcount : 최근 실행된 sql문의 결과 행 수
- %notfound : 결과집합에서 fetch된 행이 존재하면 f , 존재하지않으면 t
- %found : 결과집합에서 fetch된 행이 존재하면 t , 존재하지않으면 f
- %isopen : 최근 실행된 sql문 커서가 open상태면 t
--암시적 커서 확인
declare
v_emp_id employee.emp_id%type := '&사번';
v_emp_name employee.emp_name%type;
begin
select
emp_name
into
v_emp_name
from
employee
where
emp_id = v_emp_id;
if sql%found then
dbms_output.put_line('조회된 행수 : ' || sql%rowcount);
end if;
end;
/
--명시적 커서 확인
- 선언 - open - fetch - close
- 직접 결과집합에 접근해 행에 대한 처리가 가능
- for..in문 안에서 open/close를 자동처리해서 간단히 커서를 사용할 수 있다
declare
-- 커서선언
cursor mycursor
is
select * from employee where 1 = 0;
erow employee%rowtype;
begin
-- 커서 open
open mycursor;
loop
-- 커서 fetch
fetch mycursor into erow; -- 한행씩 가져오기
exit when mycursor%notfound; -- 더이상 가져올 행이 없는 경우, exit
dbms_output.put_line('사번 ' || erow.emp_id || ' 사원명 : ' || erow.emp_name );
end loop;
-- 커서 close
close mycursor;
end;
/
ex)
for..in문에서 명시적 커서 사용하기
open,fetch,close대신 처리
fetch된 행을 담을 변수도 for..in안에서 선언
별도의 exit 작성 불필요
declare
-- 커서선언
cursor mycursor
is
select * from employee;
begin
-- open, fetch, close 자동처리
for erow in mycursor loop
dbms_output.put_line('사번 ' || erow.emp_id || ' 사원명 : ' || erow.emp_name );
end loop;
end;
/
--매개변수가 있는 커서
--커서 선언 시 매개변수도 함께 선언
--open시 매개인자 전달
declare
cursor cs_emp_by_dept(p_dept_code employee.dept_code%type)
is
select * from employee where dept_code = p_dept_code;
v_dept_code employee.dept_code%type := '&부서코드';
erow employee%rowtype;
begin
dbms_output.put_line('사번 사원명 부서코드');
dbms_output.put_line('=========================');
for erow in cs_emp_by_dept(v_dept_code) loop
dbms_output.put_line(erow.emp_id || ' ' || erow.emp_name || ' ' || erow.dept_code);
end loop;
end;
/
'학원 > 강의' 카테고리의 다른 글
*45일차 (jdbc) (0) | 2022.03.30 |
---|---|
*44일차 (2) - 트리거(trigger) (0) | 2022.03.30 |
*43일차- ncs테스트(SQL 활용) (0) | 2022.03.28 |
*42일차 (index / PL'SQL / 조건문 / 반복문) (0) | 2022.03.26 |
*41일차 (DCL / TCL / DATABASE OBJECT 1) (0) | 2022.03.25 |