-- PL/SQL
-- 세팅
;
SET SERVEROUTPUT ON;
-- 데이터 타입 확인
DESC STUDENT;
-- 6. 레코드
-- 테이블 생성
ㅁㅁㅁㅁㅁㅁㅁㅁㅁㅁㅁㅁㅁ
스튜던트_레코드라는 테이블을 만든다. 스토던트를 참조해서;
CREATE TABLE STUDENT_RECORD
AS
SELECT *
FROM STUDENT;
-- 레코드 생성
ㅁㅁㅁㅁㅁㅁㅁㅁㅁㅁㅁㅁㅁㅁ STU_REC라는 레코드를 만드는데 거기에 들어가는 요소들의 타입이랑 의미를 정의
그리고 STU_REC레코드를 인스턴스화.STUDENTREC 이름으로
거기에 각각 요소를 인서트함
그걸 위에만든 테이블인 student_record 테이블 에 넣음
;
DECLARE
--레코드 선언부
TYPE STU_REC IS RECORD
(
--데이터가 저장될 테이블의 칼럼의 순서와 타입을 모두 동일하게 맞춰아한다.
SNO VARCHAR2(8) NOT NULL := '11012',
--notnull로 정의된 변수는 초기치를 할당하여야 합니다.
-- SNO VARCHAR2(8) NOT NULL,
SNAME STUDENT.SNAME%TYPE,
SEX STUDENT.SEX%TYPE,
SYEAR NUMBER(1, 0) DEFAULT 1,
MAJOR STUDENT.MAJOR%TYPE,
AVR STUDENT.AVR%TYPE
);
STUDENTREC STU_REC;
BEGIN
STUDENTREC.SNO := '11011';
STUDENTREC.SNAME := '문동주';
STUDENTREC.SEX := '여';
STUDENTREC.MAJOR := '컴공';
STUDENTREC.AVR := 2.5;
DBMS_OUTPUT.PUT_LINE(STUDENTREC.SNO);
DBMS_OUTPUT.PUT_LINE(STUDENTREC.SNAME);
DBMS_OUTPUT.PUT_LINE(STUDENTREC.SEX);
DBMS_OUTPUT.PUT_LINE(STUDENTREC.MAJOR);
DBMS_OUTPUT.PUT_LINE(STUDENTREC.SYEAR);
DBMS_OUTPUT.PUT_LINE(STUDENTREC.AVR);
INSERT INTO STUDENT_RECORD VALUES STUDENTREC;
END;
/
CREATE TABLE STUDENT_RECORD2
AS
SELECT *
FROM STUDENT;
-- 저장된 데이터 확인
SELECT *
FROM STUDENT_RECORD
WHERE SNO = '11012';
데이터수정;
;;
--레코드 선언부
--;;
//////////////////////////////////////
11012 이건 뭐냐?
//////////////////////////////////////
11012 이건 뭐냐?
//////////////////////////////////////
11012 이건 뭐냐?
//////////////////////////////////////
11012 이건 뭐냐?
//////////////////////////////////////
11012 이건 뭐냐?
//////////////////////////////////////
11012 이건 뭐냐?
//////////////////////////////////////
11012 이건 뭐냐?
//////////////////////////////////////
11012 이건 뭐냐?
//////////////////////////////////////
11012 이건 뭐냐?
;;--
------
;
ㅁㅁㅁㅁㅁㅁㅁㅁㅁㅁㅁㅁㅁㅁ STU_REC라는 레코드를 만드는데 거기에 들어가는 요소들의 타입이랑 의미를 정의
그리고 STU_REC레코드를 인스턴스화.STUDENTREC 이름으로
거기에 각각 요소를 인서트함(넣기 위해 준비해줌)
update student_record
set
row = studentrec
or
major = studentrec.major,
avr = studentrec.avr,
syear = studentrec.syear
where sno = '11011';
이런형식으로
insert 말고 업데이트 형식으로 바꿔줌.;;;;
;
DECLARE
TYPE STU_REC IS RECORD
(
--데이터가 저장될 테이블의 칼럼의 순서와 타입을 모두 동일하게 맞춰아한다.
SNO VARCHAR2(8) NOT NULL := '11012',
SNAME STUDENT.SNAME%TYPE,
SEX STUDENT.SEX%TYPE,
SYEAR NUMBER(1, 0) DEFAULT 1,
MAJOR STUDENT.MAJOR%TYPE,
AVR STUDENT.AVR%TYPE
);
STUDENTREC STU_REC;
BEGIN
STUDENTREC.SNO := '11011';
STUDENTREC.SNAME := '문동주';
STUDENTREC.SEX := '여';
STUDENTREC.MAJOR := '생물';
STUDENTREC.AVR := 3.5;
studentrec.SYEAR := 3;
--데이터수정
update student_record
set
row = studentrec
--or
-- major = studentrec.major,
-- avr = studentrec.avr,
-- syear = studentrec.syear
where sno = '11011';
END;
/
SELECT *
FROM STUDENT_RECORD
WHERE SNO = '11011';
-- //;;;;;;;;;;;;;;;;;;;;;;
-- 이너레코드 만들기;;;;;;;;;;;;;;;;;;;;;;
-- ㅁㅁㅁㅁㅁㅁㅁㅁㅁㅁㅁㅁㅁㅁㅁㅁㅁ stu_rec 안에 stu_rec가 있는 구조;;
-- score_rec타입 정의하고 stu_rec타입 정의하고
-- begin
-- select
-- into 식으로 집어넣는다
-- 아마 중첩으로 정의하면 그냥 바로 값을 넣을 수 있나보다
-- 출력해낼때는는 a.b.score 이런식으로 해야되니ㅏ보다
--
--
-- ;;/
declare
type score_rec is record
(
cno score.cno%type,
sno score.sno%type,
result score.result%type
);
type stu_rec is record
(
SNO VARCHAR2(8) NOT NULL := '11012',
SNAME STUDENT.SNAME%TYPE,
SEX STUDENT.SEX%TYPE,
SYEAR NUMBER(1, 0) DEFAULT 1,
-- 널이 들어와도 1로 잡힘
MAJOR STUDENT.MAJOR%TYPE,
AVR STUDENT.AVR%TYPE,
scorerec score_rec
);
studentrec stu_rec;
begin
select st.sno,
st.sname,
st.sex,
st.syear,
st.major,
st.avr,
sc.cno,
sc.sno,
sc.result
-------------------------------아 인투는 뭘 의미하는가
-------------------------------아 인투는 뭘 의미하는가
-------------------------------아 인투는 뭘 의미하는가
-------------------------------아 인투는 뭘 의미하는가
--- 아마 그 테이블에 집어 넣는다는걸 의미하는듯.
into studentrec.sno, studentrec.sname , studentrec.sex, studentrec.SYEAR, studentrec.MAJOR, studentrec.avr, studentrec.scorerec.cno, studentrec.scorerec.sno, studentrec.scorerec.result
from student st
join score sc on st.SNO = sc.sno
where st.SNO = '915601'
and sc.cno = '2368';
dbms_output.PUT_LINE(studentrec.sno);
dbms_output.PUT_LINE(studentrec.sname);
dbms_output.PUT_LINE(studentrec.syear);
dbms_output.PUT_LINE(studentrec.major);
dbms_output.PUT_LINE(studentrec.avr);
dbms_output.PUT_LINE(studentrec.scorerec.result);
end;
/
declare
geg number := 4;
begin
dbms_output.PUT_LINE(geg);
end;
/
-- 연관배열연관배열연관배열연관배열연관배열연관배열연관배열연관배열연관배열연관배열연관배열ㅍ 연관배열연관배열연관배열연관배열연관배열연관배열연관배열연관배열연관배열연관배열ㅍ
--
--
--
-- 동일한 데이터 타입의 데이터들을 모아놓은 자료형;
-- 배열을 만드는데 numarr(1) = 이런 배열을 만들어라. 루프를만들어서;;
declare
type number_array is table of number
index by pls_integer;
num number := 0;
numarr number_array;
begin
loop
num := num + 1;
numarr(num) := num;
exit when num > 5;
end loop;
DBMS_OUTPUT.PUT_LINE(numarr(1));
DBMS_OUTPUT.PUT_LINE(numarr(2));
DBMS_OUTPUT.PUT_LINE(numarr(3));
DBMS_OUTPUT.PUT_LINE(numarr(4));
DBMS_OUTPUT.PUT_LINE(numarr(5));
end;
/
-- 레코드와 배열을 조합하여 레코드타입의 배열 생성(자바의 객체 배열과 비슷);
-- stu_rec의 요소 타입들 정ㅇ의해놓고
-- %%이건 그냥 출력만 하는거%%%
-- stu_rec의 배열 student_array이다.
-- 루프를 넣는다.
-- 루프에서 1에서 10까지 돌려서 넣음;
declare
type stu_rec is record
(
SNO VARCHAR2(8) NOT NULL := '11012',
SNAME STUDENT.SNAME%TYPE,
SEX STUDENT.SEX%TYPE,
SYEAR NUMBER(1, 0) DEFAULT 1,
MAJOR STUDENT.MAJOR%TYPE,
AVR STUDENT.AVR%TYPE
);
--레코드 타입의 배열 선언
type student_array is table of stu_rec
index by pls_integer;
stuarr student_array;
idx number := 1;
begin
loop
stuarr(idx).sno := 10000 + idx;
stuarr(idx).SNAME := 'A';
stuarr(idx).SYEAR := mod(idx, 4) + 1;
stuarr(idx).MAJOR := '컴공';
DBMS_OUTPUT.PUT_LINE(stuarr(idx).sno);
DBMS_OUTPUT.PUT_LINE(stuarr(idx).sname);
DBMS_OUTPUT.PUT_LINE(stuarr(idx).syear);
DBMS_OUTPUT.PUT_LINE(stuarr(idx).major);
idx := idx + 1;
exit when idx > 10;
end loop;
end;
/
-- /;;
-- ㅁㅁㅁㅁㅁㅁㅁㅁㅁㅁㅁㅁㅁㅁㅁㅁㅁㅁㅁㅁㅁㅁㅁㅁ /////////////////////////////////
-- 레코드 하나를 정의해서
--
-- 배열 안에 넣은거;;;
-- 레코드와 배열을 조합하여 레코드타입의 배열 생성(자바의 객체 배열과 비슷);
-- stu_rec의 요소 타입들 정ㅇ의해놓고
-- stu_rec의 배열 student_array이다.
-- 루프를 넣는다.
-- 루프에서 1에서 10까지 돌려서 넣음
--
--
-- 이걸 출력하지 않고 student_record에 넣는다.;
declare
type stu_rec is record
(
SNO VARCHAR2(8) NOT NULL := '11012',
SNAME STUDENT.SNAME%TYPE,
SEX STUDENT.SEX%TYPE,
SYEAR NUMBER(1, 0) DEFAULT 1,
MAJOR STUDENT.MAJOR%TYPE,
AVR STUDENT.AVR%TYPE
);
--레코드 타입의 배열 선언
type student_array is table of stu_rec
index by pls_integer;
stuarr student_array;
idx number := 1;
begin
loop
stuarr(idx).sno := 10000 + idx;
stuarr(idx).SNAME := 'A';
stuarr(idx).SYEAR := mod(idx, 4) + 1;
stuarr(idx).MAJOR := '컴공';
insert into student_record
values stuarr(idx);
idx := idx + 1;
exit when idx > 10;
end loop;
end;
/;
select *
from STUDENT_RECORD
where sno like '1000%';
--rowtype을 이용해서 연관배열 생성
-- ㅁㅁㅁㅁㅁㅁㅁㅁㅁㅁㅁㅁㅁㅁㅁㅁㅁㅁㅁㅁㅁㅁㅁㅁㅁㅁㅁ 아예 student에서 타입들을 rowtype로 가져와서
-- 로우배열을 만들엇 넣는것.
-- 스튜던트의 로우타입을 갖고와서 하는거. 처음에 정의를 할 필요가 전혀 없음;;
declare
type stu_array is table of student%rowtype
index by pls_integer;
idx number := 1;
stuarr stu_array;
begin
loop
stuarr(idx).sno := 20000 + idx;
stuarr(idx).sname := 'B' || idx;
stuarr(idx).MAJOR := '소프트웨어';
stuarr(idx).syear := mod(idx, 4) + 1;
insert into STUDENT_RECORD
values stuarr(idx);
idx := idx + 1;
exit when idx > 10;
end loop;
end;
/
select *
from student_record
where sno like '2000%';
declare
-- exist함수는 true/false를 리턴하기 때문에 출력하는 매개변수로 사용불가
--if 나 case조건절에 사용한다.
--dbms_output.put_line(stuarr.exists(1))
type stu_array is table of student%rowtype
index by pls_integer;
stuarr stu_array;
begin
stuarr(1).sno := 20000 + 1;
stuarr(1).sname := 'B' || 1;
stuarr(1).MAJOR := '소프트웨어';
stuarr(1).syear := 1;
stuarr(2).sno := 20000 + 2;
stuarr(2).sname := 'B' || 2;
stuarr(2).MAJOR := '소프트웨어';
stuarr(2).syear := 2;
stuarr(3).sno := 20000 + 3;
stuarr(3).sname := 'B' || 3;
stuarr(3).MAJOR := '소프트웨어';
stuarr(3).syear := 3;
stuarr(10).sno := 20000 + 10;
stuarr(10).sname := 'B' || 10;
stuarr(10).MAJOR := '소프트웨어';
stuarr(10).syear := 4;
-- DBMS_OUTPUT.PUT_LINE(stuarr.EXISTS(4));
DBMS_OUTPUT.PUT_LINE(stuarr.count);
-- DBMS_OUTPUT.PUT_LINE(stuarr.first);
-- DBMS_OUTPUT.PUT_LINE(stuarr.last);
DBMS_OUTPUT.PUT_LINE(stuarr.prior(10));
DBMS_OUTPUT.PUT_LINE(stuarr.next(10));
stuarr.DELETE(3);
DBMS_OUTPUT.PUT_LINE(stuarr.count);
if stuarr.EXISTS(3) then
DBMS_OUTPUT.PUT_LINE('3번 인덱스 있음');
else
DBMS_OUTPUT.PUT_LINE('3번 인덱스 없음');
end if;
end;
/
--아까 했던 into도 커서의 한 종류라고 볼 수 있음 명시적으로 커서를 사용하지는 않았찌만
-- 1 - 8 커서
-- 한 행만 조사하는 커서;;;;;;;;;;;;;;
--쿼리의 결과를 저장하는 쿼리
declare
--커서선언
-- sno가 915301인 student 정보 가져와서 curst를 만들어서 넣어서
--strec 레코드를 만든다음에 커스트를 sturec에 밀어넣는것
--출력하고 curst는 닫는다.
--과정 1. declare에 curst극 정의한다. student에서 sno, sname, major, syear을 불러온다. sno가 915301인것을
--strec 레코드를 정의하고 거기 안에 있는 요소들의 타입을 정의 strec의 인스턴스화 sturec를 만듬
-- curst를 열어서 인스턴스화된 sturec에 집어넣음
--그걸 출력함
cursor curst is
select sno, SNAME, major, syear
from student
where sno = '915301';
type strec is record
(
sno varchar2(8),
sname varchar2(20),
major varchar2(20),
syear number(1, 0)
);
sturec strec;
begin
open curst;
fetch curst into sturec;
DBMS_OUTPUT.PUT_LINE(sturec.sno);
DBMS_OUTPUT.PUT_LINE(sturec.sname);
DBMS_OUTPUT.PUT_LINE(sturec.major);
DBMS_OUTPUT.PUT_LINE(sturec.syear);
close curst;
end;
/
--여러개의 행을담고 있는 커서의 처리 방식;
--1학년인 애들을 다 가져오는거
-- declare에 curst극 정의한다. student에서 sno, sname, major, syear을 불러온다. syear가 1인것을
--로우에 집어넣을껀데 student의 rowtype인 strow를 정의
-- 루프를 만들어서 curst를 열어서 인스턴스화된 strow 집어넣음
--curst에 더이상 정보가 없으면 끝내게
--그걸 출력함
declare
cursor curst is
select sno, sname, sex, syear, major, avr
from student
where syear = 1;
strow student%rowtype;
begin
open curst;
loop
fetch curst into strow;
DBMS_OUTPUT.PUT_LINE(strow.SNO);
DBMS_OUTPUT.PUT_LINE(strow.SNAME);
DBMS_OUTPUT.PUT_LINE(strow.SYEAR);
DBMS_OUTPUT.PUT_LINE(strow.major);
exit when curst%notfound;
end loop;
close curst;
end;
/
--여러행을 담고있는 CUrsor의 for 루프 처리
--여러개의 행을담고 있는 커서의 처리 방식;
--1학년인 애들을 다 가져오는거
-- declare에 curst극 정의한다. student에서 sno, sname, major, syear을 불러온다. syear가 1인것을
--여긴 for문으로 할꺼다
--curse에서 strow를 꺼낸다.
--루프를 열어서
--그걸 출력함
declare
cursor curst is
select sno, sname, sex, syear, major, avr
from student
where syear = 1;
begin
--자동 open, fetch, close 일어난다.
--월신 간단함. 변수 선언 해줄필용도없고....
for strow in curst
loop
DBMS_OUTPUT.PUT_LINE(strow.SNO);
DBMS_OUTPUT.PUT_LINE(strow.SNAME);
DBMS_OUTPUT.PUT_LINE(strow.SYEAR);
DBMS_OUTPUT.PUT_LINE(strow.major);
end loop;
end;
/
--커서의 파라미터
-- 고정된 쿼리 결과가 아닌 유동적인 쿼리의 결과를 커서에 담아준다.
-- 유동적인 데이터를 가져올 수 있는 커서를 만들 수 있음
--curst(param) 에 파라미터 안에 syear을 넣어서 정보를 가져오고싶다.
--cursor를 정의. sno, sname, major, syear를 가져올 수 있또록. 그리고 strec 레코드를 정의 그리고 strec sturec로 인스턴스화
-- curst(2)를 열고 curst를 sturec를 넣어서 출력함
--curst를 닫음
-- 또 curst(4)를 열고 가져오고 닫음
declare
cursor curst (param_syear number) is
select sno, sname, major, syear
from student
where syear = param_syear;
type strec is record
(
sno student.sno%type,
sname student.sname%type,
major student.major%type,
syear student.syear%type
);
sturec strec;
--패치로 한줄씩 받아야하니까
begin
open curst(2);
loop
fetch curst into sturec;
exit when curst%notfound;
DBMS_OUTPUT.PUT_LINE('-----------------------------------------------2학년데이터');
DBMS_OUTPUT.PUT_LINE(sturec.SNO);
DBMS_OUTPUT.PUT_LINE(sturec.SName);
DBMS_OUTPUT.PUT_LINE(sturec.MAJOR);
DBMS_OUTPUT.PUT_LINE(sturec.Syear);
end loop;
close curst;
open curst(4);
loop
fetch curst into sturec;
exit when curst%notfound;
DBMS_OUTPUT.PUT_LINE('-----------------------------------------------4학년데이터');
DBMS_OUTPUT.PUT_LINE(sturec.SNO);
DBMS_OUTPUT.PUT_LINE(sturec.SName);
DBMS_OUTPUT.PUT_LINE(sturec.MAJOR);
DBMS_OUTPUT.PUT_LINE(sturec.Syear);
end loop;
close curst;
end;
/
--묵시적 커서
--실행된 쿼리문의 결과를 담고있는 커서
--따로 커리를 선언하지 않는다.
-- student에서 syear가 0인걸 다 1로 바꿔라;
--바뀐 row가 몇개인지 나오게
--------------------------이거 왜 rowcount 안돼냐
--------------------------이거 왜 rowcount 안돼냐
--------------------------이거 왜 rowcount 안돼냐
--------------------------이거 왜 rowcount 안돼냐
--------------------------이거 왜 rowcount 안돼냐
begin
update student
set syear = 1
where syear = 0;
DBMS_OUTPUT.PUT_LINE(sql%rowcount);
end;
select *
from student
where syear = 0;
--------------------------이거 왜 rowcount 안돼냐
--------------------------이거 왜 rowcount 안돼냐
--------------------------이거 왜 rowcount 안돼냐
--------------------------이거 왜 rowcount 안돼냐
--------------------------이거 왜 rowcount 안돼냐
-- 1-9 예외처리
-- -exception으로 예외처리
declare
val_sno number;
begin
select sname
into val_sno
from student
where sno = '915301';
DBMS_OUTPUT.PUT_LINE('예외발생 시 실행안됨');
exception
when VALUE_ERROR then
DBMS_OUTPUT.PUT_LINE('수치가 부적합합니다');
rollback;
end;
/
--update시 에러발생 처리 rollback
--- val_sno가 'A'인데 student의 syear에 넣는다. 예외처리 나오고 sqlcode, sqleerm 나오게 해라 롤백도 하게 해라
declare
val_sno varchar2(10);
begin
--숫자에 A를 넣을수 없으니 익셈션 발생할테니 수치부적함 하고 롤백 완료될꺼다 아마
val_sno := 'A';
update student
set syear = val_sno
where sno = '915301';
DBMS_OUTPUT.PUT_LINE('예외발생 시 실행안됨');
exception
when INVALID_NUMBER then
DBMS_OUTPUT.PUT_LINE('수치가 부적합합니다');
rollback;
DBMS_OUTPUT.PUT_LINE('롤백완료');
end;
/
declare
val_sno varchar2(10);
begin
--숫자에 A를 넣을수 없으니 익셈션 발생할테니 수치부적함 하고 롤백 완료될꺼다 아마
val_sno := 'A';
update student
set syear = val_sno
where sno = '915301';
DBMS_OUTPUT.PUT_LINE('예외발생 시 실행안됨');
exception
when value_error then
DBMS_OUTPUT.PUT_LINE('수치가 부적합합니다');
rollback;
DBMS_OUTPUT.PUT_LINE('롤백완료');
when too_many_rows then
DBMS_OUTPUT.PUT_LINE('수치가 부적합합니다');
rollback;
DBMS_OUTPUT.PUT_LINE('롤백완료');
when program_error then
DBMS_OUTPUT.PUT_LINE('수치가 부적합합니다');
rollback;
DBMS_OUTPUT.PUT_LINE('롤백완료');
when others then
DBMS_OUTPUT.PUT_LINE(sqlcode);
DBMS_OUTPUT.PUT_LINE(sqlerrm);
rollback;
DBMS_OUTPUT.PUT_LINE('롤백완료');
end;
/
-----------------------왜 안들어갈텐데 롤백을 해야 하는ㄴ지!?!?!?
-----------------------그냥 엑셉션 다 합해진 에러 없는지?!!?!?!?!!?
-----------------------왜 안들어갈텐데 롤백을 해야 하는ㄴ지!?!?!?
-----------------------그냥 엑셉션 다 합해진 에러 없는지?!!?!?!?!!?-----------------------왜 안들어갈텐데 롤백을 해야 하는ㄴ지!?!?!?
-----------------------그냥 엑셉션 다 합해진 에러 없는지?!!?!?!?!!?-----------------------왜 안들어갈텐데 롤백을 해야 하는ㄴ지!?!?!?
-----------------------그냥 엑셉션 다 합해진 에러 없는지?!!?!?!?!!?
댓글 영역