일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- SQLD 핵심포인트
- java 함수
- java 성별
- java 로또
- java 상속
- java Fish
- sqld 옵티마이져
- java 구구단
- SQLD 특강
- java Animal
- sqld deny
- SQLD 옵티마이저
- JAVA 연산자
- JAVA 제어문
- java string
- sqld remame
- JAVA for문
- sqld 자격증
- sqld grant
- sqld revoke
- SQLD 자격시험 개념정리
- java
- Java 메소드
- sqld trigger
- SQL
- java spider
- PLSQL
- java 논리연산자
- java 단축키
- Java Cat
- Today
- Total
SQLD, ECLIPS, JAVA,PYTHON, NODE....
[Oracle] PL/SQL Class 5 - replace procedure, sequence, replace function, 아웃풋, 과제(3문제) 본문
[Oracle] PL/SQL Class 5 - replace procedure, sequence, replace function, 아웃풋, 과제(3문제)
D_Aiden 2023. 11. 13. 09:552023.11.13
(설명1)
drop table sawon_ex;
create table sawon_ex as select *from sawon;
create or replace procedure p_sawon_del
(v_bun in sawon_ex.sabun%type) // in 생략 가능(기본값) 단, out시에는 입력필요.
is
begin
delete sawon_ex where sabun =v_bun;
end;
/
-- 호출형태
exec p_sawon_del(15) // 15번 사원을 삭제(del)하라는 명령어
(연습1)
-- 사원 테이블에 사원정보를 입력하는 프로시져
-- 사원은 시퀀스를 이용하고(201~299, 2씩 증가)
-- 입사일은 현재날짜로 입력되고
-- 커미션은 직책 조건에 따라 입력(직책이 대리 --> 급여 10%, 과장 --> 급여15%, 부장 --> 급여 20%, 그 외 직책 -->0)
-- 관리자번호는 부서사 영업부는 3번 사번입력, 총무부는 10번 사번입력, 전산부는 6번 사번을 입력되도록 한다.
-- 호출형태
-- exec p_sawon_in('홍동우', 3000, '대리', '남자', '영업부'); // 입력( in )하라는 명령어
create sequence s_sawon_sabun
increment by 2 // 2개씩 증가
start with 201 // 시작하는 숫자
maxvalue 299; // 끝나는 숫자
create or replace procedure p_sawon_in
(v_saname sawon.saname%type,
v_sajob sawon.sajob%type,
v_sapay sawon.sapay%type,
v_sasex sawon.sasex%type,
v_dname dept.dname%type,
v_samgr sawon.samgr%type );
is
-- dname_dept dept.deptno%type;
-- v_comm sawon.comm%type;
begin
-- select sajob, comm, sapay, into v_job, v_comm, v_pay from sawon;
-- if v_job='대리' then v_comm=v_pay*0.1;
-- elsif v_job='과장' then v_comm=v_pay*0.15;
-- elsif v_job='부장' then v_comm=v_pay*0.2;
-- else v_comm=0;
-- end if;
-- if d.name = '영업부' then v_smgr :=3;
-- elsif d.name = '총무부' then v_smgr :=10;
-- elsif d.name = '전산부' then v_smgr :=6;
-- end if;
insert into sawon(sabun, saname, sapay, sajob, deptno, comm, smgr, sahire)
-- values(v_sabun, v_name, v_job, v_sahire, v_comm, v_deptno, v_smgr);
values(s_sawon_sabun.nextval, v_saname, v_sapay, v_sajob, v_sex,
(select deptno from dept where dname=v_dname),
(case v_sajob when '대리' then v_sapay*0.1 when '과장' then v_sapay*0.15 when '부장'
then v_sapay*0.2 else 0 end), v_samge, sysdate);
commit;
end;
/
(참고)
1. 오류 확인 방법
SQL> show error procedure 테이블명(프로시저명)

2. 오류보는 방법
SQL> desc user_errors // object_type 컬럼에서 객체지정 필요.

3. 오류객체 보는 방법
SQL> user_objects 테이블명 // 객체의 정보
(연습2)
-- 사원 테이블에 사원 정보를 변경하는 프로시저
-- 호출형태
-- exec p_sawon_up(201, 3500, '과장', '관리부') --> 201번 사원의 정보를 지정한 값들로 변경
-- 커미션은 직책의 조건에 따라 입력(직책이 대리 --> 급여10%, 과장-->급여의 15%, 부장 --> 급여의 20%, 그 외의 직책-->0)
-- 관리자번호는 부서가 영업부면 3번 사번입력, 총무부는 10번 사번입력, 전산부는 6번사번 입력 되도록 한다.
create or replace procedure p_sawon_up(
v_sabun sawon.sabun%type,
v_sapay sawon.sapay%type,
v_sajob sawon.sajob%type,
v_dname dept.dname%type)
is
begin
select deppno into b_deptno from dept where dname=v_dname; // 부서번호
if v_dname = '영업부' then v_mgr := 3;
elsif v_dname = '총무부' then v_mgr :=10;
elsif v_dname = '전산부' then v_mgr :=6;
end if;
if v_job = '대리' then v_comm := v_sal*0.1;
elsif v_job = '과장' then v_comm := v_sal*0.15;
elsif v_job = '부장' then v_comm := v_sal*0.2;
else v_comm :=0;
end if;
update sawon
set sapay = v_sal, deptno = v_deptno, sajob=v_job, comm=v_comm, samgr=v_mgr
where sabun = v_bun;
-- update sawon
-- set sapay = v_sapay, sajob=v_sajob,
-- deptno=(select deptno from dept where dname=v_dname),
-- comm=(case v_sajob when '대리' then v_sapay*0.1 when '과장' then v_sapay*0.15 when '부장' then v_sapay)
-- samgr=(case v_dname when '영업부' then 3 when '총무부' then 10 when '전산부' then 6 end)
-- where sabun=v_sabun;
commit;
end;
end;
/

(설명3)
## out mode가 있는 프로시저(외부 컴퓨터(로컬 서버 or 서버)에서 내 컴퓨터(서버 or 로컬서버)로 접속해 DB 확인 방법)
-- 사번을 가지고 이름을 리턴해주는 프로시저를 생성
create or replace procedure p_name_output
(v_bun in sawon.sabun%type
v_name out sawon.sanme%type)
is
begin
select saname into v_name from sawon where sabun=v_bun;
end;
/
호출형태(SQL 내에서 입력)
SQL> variable name varchar2(100) // 1. 외부변수 선언
SQL> exec p_name_output(12, ;name) // 2. 프로시저 호출
SQL> print name // 3. 변수 출력
(연습3)
---해당 입사년도에 입사한 사원의 인원수와 평균급여를 출력하는 프로시저
-- 호출형태
-- SQL> variable result varchar2(100)
-- SQL> exec p_state(1990, :result)
-- SQL> print result // [1990년 입사한 사원은 XX명, 평균급여는 XXXX이다] 형태로 출력
** SQL내에서 직접입력(외부 명령, 아웃풋)
--SQL> variable name varchar2(100) // 1. 외부변수 선언
--SQL> exec p_name_output(12, :name) // 2. 프로시저 호출
--SQL> print name // 3. 변수 출력
(연습4)
-- out mode가 있는 프로시저
-- 사번을 가지고 이름을 리턴해주는 프로시저를 생성
create or replace procedure p_state(year in number, output out varchar2)
is
cnt number(3);
pay_avg number(10,2);
begin
select count(*), avg(sapay) into cnt, pay_avg from sawon where to_char(sahire, 'yyyy') = year;
output := '입사년도: ' || year || ', 인원수: ' || cnt || ',평균급여: ' || pay_avg;
end;
/
명령 프롬프트 내에서 명령어를 입력해서 결과 값 확인하는 방법(아웃풋 이라고 함. output)
SQL> variable result varchar2(100)
SQL> exec p_state(1990, :result)
SQL> print result

## Function (함수)
함수는 대상테이블이 없고, 호출만 해서 사용하므로 성능은 좋음
-- 반복되고 복잡하고
-- 리턴값이 반드시 1개 존재
-- 이름의 성을 제외한 이름만 추출하는 함수
create or replace functon f_name (name varchar2 )
return varchar2
is
begin
return substr(name, 2, 4);
end;
/
SQL> select saname, f_name(saname) name from sawon;

SQL> select saname, f_name(saname) name from sawon;

(연습5)
-- 주민번호 형태의 데이터를 가지고 성별을 반환하는 함수
-- 호출형태
-- select goname, f_sex(gojumin) "성별" from gogek;
create or replace function f_sex (num varchar2)
return varchar2
-- (혹은 다른 방법)
-- create or replace function f_sex (num varchar2)
--
is
sex_num number(1);
begin
return case when substr(num, 8, 1) = 1 then '남자' else '여자'
-- (혹은 다른 방법)
-- sex_num := substr(v_jumin, 8, 1);
-- if sex_num = 1 or sex_num = 3 then return '남자';
-- else return '여자';
-- end if;
end;
end;
/
실행방법
SQL> select goname, f_sex(gojumin) "성별" from gogek;

(연습6)
-- 숫자형태의 데이터를 가지고 100의 " # " 하나를 반환하는 함수
-- 호출형태
-- select saname, f_star(sapay) 급여현황 from sawon;
create or replace function f_star (star number)
return varchar2
is
begin
return lpad( '*', star/100, '*'); // 100개당 하나를 #로 찍는 방법
end;
/
SQL> select saname, f_star(sapay) from sawon;
참고: col 테이블명 format a50 // (50은 최대길이 값) 입력해 가지런히 정렬.....
Load( "값","총 문자길이","채움문자") // 왼쪽부터 정렬
Rpad ("값","총 문자길이","채움문자") // 오른쪽부터 정렬

(과제1)
1. 날짜 형태의 값을 가지고 [xx년 xx개월]형태로 기간을 반환하는 함수
-- 호출형태
-- col star format a50
-- col 근무기간 format a20
-- select saname, sapay, f_star(sapay) star, sahire, f_gigan(sahire) 근무기간 from sawon;
create or replace function f_gigan(hire_date date)
return varchar2
is
begin
return floor(months_between(sysdate, hire_date)/12) || ' 년 ' ||
floor(mod(months_between(sysdate, hire_date),12)) || ' 개월';
end;
/
(남교수님 정답)
create or replace function f_gigan(v_date date)
return varchar2
is
begin
return floor(months_between(sysdate, v_sahire)/12) || '년 ' ||
floor(mod(months_between(sysdate, v_sahire), 12)) || '개월';
end;
/

2. 날짜에 년수, 개월수, 날수를 매개변수로 보내 더하는 함수를 생성하라
-- (입사일로부터 년 수/개월/일 을 더해서 출력하는 함수)
-- 입사일로부터 3년 1개월 3일 더한값 출력
-- 적용 예) select saname, sahire, add_date(sahire, 3, 1, 3) "심사일" from sawon;
create or replace function add_date (v_date date,
v_year number,
v_mon number,
v_day number)
return date
is
begin
return add_months(v_date, v_year*12+v_mon)+v_day;
// add_months(date, integer)-지정한 날짜에서 해당 월에 일정한 정수 (혹은 마이너스 정수)값을 더한 날짜를 반환
end;
/
(남교수님 정답)
create or replace function add_date(
v_hire date,
year number,
month number,
day number)
return date
is
begin
return add_months(v_hire,((year*12)+month))+day;
end;
/

3. 주민번호를 가지고 나이를 계산하는 함수를 생성하라.
--적용 예) select goname, gojumin, f_jumin_age(gojumin) age from gogek;
create or replace function f_jumin_age
(birth varchar2)
return number
is
v_age number;
begin
if substr(birth, 8, 1) in (1, 2) then
v_age := to_number(to_char(sysdate, 'yyyy')) - (substr(birth, 1, 2)+1900);
else
v_age := to_number(to_char(sysdate, 'yyyy')) - (substr(birth, 1, 2)+2000);
end if;
return v_age;
end;
/
(남교수님 정답)
create or replace function f_jumin_age(
jumin varchar2)
return varchar2
is
cen number(2);
year number(4);
go_year number(2);
begin
cen := substr(jumin,8,1); -- 1900년생, 2000년생 구별하기 위한 데이터
year := to_char(sysdate,'yyyy'); -- 현재의 년도 구한 데이터
go_year := substr(jumin,1,2); -- 년생 구하기
if (cen = 1 or cen = 2) then
return year-(1900+go_year)||'살';
else
return year-(2000+go_year)||'살';
end if;
end;
/

'PLSQL' 카테고리의 다른 글
[Oracle] PL/SQL Class 6 - 주민번호 유효성 체크, 트리거(trigger), 업무자동화(연습), 과제(4) (0) | 2023.11.14 |
---|---|
[Oracle] PL/SQL Class 5 - 과제 (0) | 2023.11.13 |
[Oracle] PL/SQL Class 4 - 과제2, 과제3 (2) | 2023.11.13 |
[Oracle] PL/SQL - 명령프롬프트 정리 (0) | 2023.11.10 |
[Oracle] PL/SQL Class 3 - 커서 2, 다중커서 과제, (0) | 2023.11.10 |