모두의 SQL 2번째 실습입니다.
연습환경은 Oracle Live SQL의 Code Library의 HR Object and Data For Live SQL을 이용하였습니다! 참고!
INSERT INTO
departments(
department_id,
department_name,
manager_id,
location_id
)
VALUES (
271,
'Sample_Dept',
200,
1700
)
-- 확인!
SELECT *
FROM departments
WHERE department_id > 250;
모든 컬럼에 값을 입력하는 경우, 컬럼 목록은 생략 가능하다.
또 한번, 같은 INSERT 문을 실행하는 경우에 PRIMARY가 중복을 허용하지 않을 때 에러가 발생합니다.
데이터 타입이 일치하지 않아도 에러가 납니다!
서브쿼리를 이용해서 풀어보자
departments 테이블에 새로운 부서 정보를 저장하시오.
INSERT INTO
departments (
department_id,
department_name,
manager_id,
location_id
)
VALUES (
(SELECT
-- 서브쿼리를 이용해서 +1의 값을 구할 수 있겠지
MAX(department_id) + 1
FROM departments
),
'Test_Dept', 101, 1800
);
CREATE TABLE test (
-- NUMBER도 대문자로!
ID NUMBER(5) PRIMARY KEY,
name VARCHAR2(50) NOT NULL
);
-- 이 이후에 INSERT 하려고 하면 에러가 납니다.
INSERT INTO test
VALUES (
(SELECT MAX(id) + 1
FROM test), '테스터'
);
똑같은 쿼리인데, 왜 실행이 안 되었을까?
INSERT INTO test
VALUES (
(SELECT NVL(MAX(id),0) + 1
FROM test), '테스터'
);
UPDATE departments
SET manager_id = 100,
department_name = '연구개발부'
WHERE department_id = 273;
SELECT *
FROM departments
WHERE department_id = 273;
WHERE를 안 써도 되지만, PRIMARY KEY가 정말 중요함
UNIQUE한 값들을 통해서 각각의 ROW을 구별할 수 있음
수정, 삭제에 대해서 특정 ROW만 가능하게 하는 것
SET 마지막에 ,
을 찍어서 문법 오류를 발생시키는 경우를 주의!
departments 테이블에서 부서이름이 'Sample_Dept'인 부서의 관리자 아이디와 지역 아이디를 수정하시오.
UPDATE departments
SET manager_id = 201,
location_id = 1800
WHERE department_name = 'Sample_Dept';
SELECT *
FROM departments
WHERE department_name = 'Sample_Dept';
UPDATE에서도 서브쿼리를 이용해 데이터 수정이 가능!
부서이름이 'Sample_Dept'인 부서의 관리자 아이디와 부서 위치 아이디를 273번 부서의 관리자 아이디와 부서 위치아이디로 수정하시오
서브쿼리를 통해 내가 모르는 데이터를 얻어내고, 그 검색결과를 이용해서 수정하던지, 추가작업을 이루게 하는 것
UPDATE departments
SET (manager_id,location_id) = (
SELECT manager_id, location_id
FROM departments
WHERE department_id = 273
)
WHERE department_name = 'Sample_Dept';
SELECT *
FROM departments
WHERE department_id > 270;
UPDATE departments
SET department_id = null
WHERE department_name = 'Sample_Dept';
SELECT * FROM departments
WHERE department_name = 'Sample_Dept';
DELETE
FROM departments
WHERE department_name = 'Sample_Dept';
SELECT * FROM departments
WHERE department_name = 'Sample_Dept';
주의! FK는 NULL을 허용하기 때문에
FK 기준 삭제는 아무 문제가 없지만, PK가 있는 ROW을 삭제할 때는 문제가 됩니다.
참조하고 있기 때문에 삭제하는 것이 불가능하다.
주의! employees 테이블에서 참조되고 있는 부서 데이터는 삭제할 수 없다.
UPDATE, INSERT, DELETE 모두 Sub-Query를 이용할 수 있다!
제약조건을 기술할 때는 CONSTRAINT 키워드를 특정 컬럼에 추가
PK 제약조건 위배
100번 부서를 등록한다. 기본 키 제약 조건 위배
-- PK 조건 위배
INSERT INTO departments
VALUES (100, 'Sample_Dept', 200, 1700);
FK 제약 조건 위배
1111이 없으니까 에러가 남
-- FK 조건 위배
INSERT INTO departments
VALUES (273, 'Sample_Dept', 200, 1111);
-- UK 조건 위배
INSERT INTO employees (
employee_id,
first_name,
last_name,
email,
phone_number,
hire_date,
job_id, salary
) VALUES (207, 'fist_name', 'last_name', 'SKING',
'111.111.1111', TO_DATE('030617', 'YYMMDD'),
'IT_PROG', 6000);
-- NN 조건 위배
INSERT INTO departments
VALUES (273, null, 200, 1700);
-- CHECK 조건 위배
INSERT INTO employees (
employee_id,
first_name,
last_name,
email,
phone_number,
hire_date,
job_id, salary) VALUES (207, 'fist_name', 'last_name', 'TEST',
'111.111.1111', TO_DATE('030617', 'YYMMDD'),
'IT_PROG', 0);
이 부분은 h2 Database를 통해서 실습합니다.
- 자동 커밋 해제
`SHIFT + ENTER' : RUN Selected
CTRL + ENTER
: 전체 실행
COMMIT이 되면, INSERT가 영구적으로 반영되는 것 (불가역적인)
왜 중요한가?
내 통장에서 인출한다(UPDATE)
친구 통장에 입금한다.(UPDATE)
트랜잭션 : 논리적으로 분리할 수 없는 하나 이상의 DML 작업(단, SELECT는 제외)
과정!
SELECT * FROM test
INSERT INTO TEST VALUES(2, '임호정')
SELECT * FROM test
ROLLBACK
CREATE TABLE sample_product (
product_id NUMBER,
product_name VARCHAR2(30),
manu_date DATE
);
참고! DESC는 Oracle에서만 쓸 수 있음
INSERT
INSERT INTO sample_product
VALUES(1, 'television',
CURRENT_DATE)
INSERT INTO sample_product
VALUES(2, 'washer',
CURRENT_DATE)
INSERT INTO sample_product
VALUES(3, 'cleaner',
CURRENT_DATE)
https://www.h2database.com/html/commands.html
ALTER TABLE sample_product
ADD (factory VARCHAR2(10));
ALTER TABLE sample_product
MODIFY (factory VARCHAR2(10));
ALTER TABLE sample_product
RENAME COLUMN factory TO factory_name;
ALTER TABLE sample_product
DROP COLUMN factory_name;
CREATE [OR REPLACE] VIEW AS (SELECT ~~)
OR REPLACE는 VIEW가 이미 있다면, 그 VIEW를 대체하겠다.
가만히 보니까, 두 개의 테이블을 자주 조인하게 되고, 주로 검색하는 COLUMN을 보니까 나머지 컬럼은 잘 조회하지도 않아
JOIN을 많이 하면 할 수록 성능은 떨어짐
Oracle에는 이미 존재합니다.