20230328 SQL
<차례>
❍ 유저 삭제
❍ 유저 생성
❍ 패스워드 만료
❍ TABLE
(정보 확인)
SELECTFROM dba_users;
SELECTFROM dba_data_files;
SELECT*FROM dba_temp_files;
SELECTFROM user_users; => 내꺼 내가 보겠다.
SELECTFROM user_tables;
SELECTFROM user_objects;
SELECTFROM user_views;
SELECTFROM user_indexes;
SELECTFROM user_ts_quotas;
❍ 유저 삭제
DROP USER ora CASCADE; => 트리거성, 이벤트성 프로그램
❍ 유저 생성
CREATE USER ora
IDENTIFIED BY oracle => 위 두 줄 필수
DEFAULT TABLESPACE users => 옵션이지만 보통 작성함
TEMPORARY TABLESPACE temp => 메모리에서 다 못하면 내려가는 디스크
QUOTA 1M ON USERS;
--PASSWORD EXPIRE;
[문제90] ORA 유저에게 create session, create table 시스템 권한을 부여해 주세요. (sys계정에서 수행)
GRANT create session, create table TO ORA;
SELECT*FROM dba_sys_privs WHERE grantee = ‘ORA’;
[문제91] ORA 유저가 사용할 수 있는 users tablespace quota 값을 unlimited로 수정해 주세요. (sys계정에서 수행)
SELECTFROM dba_ts_quotas WHERE username = ‘ORA’;
ALTER USER ora
QUOTA UNLIMITED ON users;
SELECTFROM dba_ts_quotas WHERE username = ‘ORA’;
[문제92] HR유저 employees 테이블의 select 권한을 ORA 유저에게 부여 하세요. (hr계정에서 수행)
SELECTFROM user_tab_privs;
GRANT select ON hr.employees TO ora;
SELECTFROM user_tab_privs;
❍ 패스워드 만료
ALTER USER ora PASSWORD EXPIRE;
SELECT*FROM dba_users;
● SQL> conn ora/oracle => Run SQL Command Line
SQL> conn ora/oracle
ERROR:
ORA-28001: the password has expired
Changing password for ora
New password:
● C:\Users\ITWILL>sqlplus ora/oracle => 명령 프롬프트
SQL*Plus: Release 11.2.0.2.0 Production on 화 3월 28 10:26:16 2023
Copyright (c) 1982, 2014, Oracle. All rights reserved.
ERROR:
ORA-01017: invalid username/password; logon denied
Enter user-name: ora
Enter password:
Connected to:
Oracle Database 11g Express Edition Release 11.2.0.2.0 - 64bit Production
❍ TABLE
SELECT*FROM session_privs; => 권한 확인1
SELECT privilege FROM user_sys_privs => 권한 확인2(동일)
UNION
SELECT privilege FROM role_sys_privs;
GRANT UNLIMITED TABLESPACE TO HR;
REVOKE UNLIMITED TABLESPACE FROM HR;
❍ 테이블 이름, 컬럼 이름, 유저 이름, 다른 객체이름, 제약조건 이름
❍ 컬럼 타입
❍ 테이블 생성
CREATE TABLE emp( => 테이블 이름은 전체 내에서 고유해야 함
id number(4), => 컬럼 이름은 테이블 내에서 고유해야 함
name varchar2(30),
day date default sysdate)
TABLESPACE users;
=> SELECT*FROM user_ts_quotas; 테이블스페이스 확인
desc emp;
SELECT*FROM user_tables;
❍ 테이블 삭제(영구 삭제, 복원 불가)
DROP TABLE emp PURGE; => 휴지통 기능X 영구히 삭제 기능
SELECT*FROM user_tables;
■ DML(Data Manipulation Language)
■ TCL(Transaction Control Language)
COMMIT : DML작업을 영구히 데이터베이스에 저장
ROLLBACK : DML작업을 영구히 데이터베이스에서 취소
SAVEPOINT : ROLLBACK 기능을 도와주는 표시자
=> commit, rollback 사용은 필수, rollback 도와주는 기능
● Transaction : 논리적으로 DML을 하나로 묶어서 처리하는 작업 단위
(실제 예시: 카드쓰기 inser -> update 된 것임!)
❍ INSERT
INSERT INTO 소유자.테이블 이름(컬럼, 컬럼, 컬럼,,,,)
VALUES(데이터, 데이터, 데이터,,,,)
=> 본인 테이블 아닌 경우 소유자 표현 필수
desc emp
insert into hr.emp(id, name, day)
values(1, '홍길동',to_date('2023-3-28','yyyy-mm-dd')); => transaction 시작
SELECT*FROM hr.emp;
▽▽▽(결과창)
ID NAME DAY
1 홍길동 23/03/28
Run SQL Command Line에서 확인시,
============= ==============
SQL> conn hr/1234
Connected.
SQL> SELECT*FROM hr.emp;
no rows selected
============= ==============
=> 영구히 저장된 것이 아니기 때문; transaction 마무리해야 함
COMMIT; => transaction 시작 시점까지 저장, transaction 종료
Run SQL Command Line에서 재확인시,
============= ==============
SQL> /
ID NAME DAY
1 홍길동 23/03/28
============= ==============
DESC EMP;
INSERT INTO hr.emp(id, name, day)
VALUES(2,'박찬호',to_date('2020/12/20','yyyy/mm/dd')); => transaction 시작
INSERT INTO hr.emp(id, name, day)
VALUES(3,'윤건',to_date('2010-10-10', 'yyyy-mm-dd'));
SELECT*FROM hr.emp; => 미리보기
ROLLBACK; => transaction 시작 시점까지 전부 취소
transaction 종료
SELECT*FROM hr.emp;
DESC emp;
● INSERT 수행시 default 값을 입력하는 방법
1)
INSERT INTO hr.emp(id,name)
VALUES(2,'나얼');
SELECT*FROM hr.emp;
▽▽▽(결과창)
1 홍길동 23/03/28
2 나얼 23/03/28 => 그래도 디폴트(sysdate)값 등록됨
2)
INSERT INTO hr.emp(id,name,day)
VALUES(3, ‘이문세’, default);
SELECT*FROM hr.emp;
3) name 컬럼에 default 값이 선언되어 있지 않은 경우 null값으로 출력됨
INSERT INTO hr.emp(id,name,day)
VALUES(4,default,default);
SELECT*FROM hr.emp;
1 홍길동 23/03/28
2 나얼 23/03/28
3 이문세 23/03/28
4 (null) 23/03/28
4) day 컬럼에 default 값이 선언되어 있더라도 null을 수행하면 null값으로 입력됨
INSERT INTO hr.emp(id,name,day)
VALUES(5,'제임스',null);
SELECT*FROM hr.emp;
1 홍길동 23/03/28
2 나얼 23/03/28
3 이문세 23/03/28
4 (null) 23/03/28
5 제임스 (null)
=> 여기서 ROLLBACK 할시 나얼(transaction 시작)부터 끝까지 취소됨
ROLLBACK;
SELECT*FROM hr.emp;
❍ UPDATE
UPDATE 소유자,테이블
SET 컬럼 – 새로운 값, 컬럼 – 새로운 값,..
WHERE 조건;
UPDATE hr.emp
SET id = 2; => transaction 시작 지점
SELECT*FROM hr.emp; => 미리보기
ROLLBACK; => transaction 시작 시점까지 전부 취소
transaction 종료
SELECT*FROM hr.emp; => 다시 확인
SELECT*FROM dba_data_files;
▽▽▽(결과에 이런 테이블스페이스 있음)
TABLESPACE_NAME
UNDOTBS1 => ROLLBACK시 이전 데이터 가져올 수 있도록 여기에 저장
● UNDO TABLESPACE 역할
UPDATE hr.emp
SET id = 2, day = to_date('2023-03-28', 'yyyy-mm-dd')
WHERE id = 5; =>transaction 시작
SELECTFROM hr.emp; => 미리보기
COMMIT; => transaction 시작 지점까지 영구히 저장, transaction 종료
SELECTFROM hr.emp;
SELECT*FROM hr.emp;
ROLLBACK;
❍ DELETE문
DELETE FROM 소유자, 테이블; => 테이블 전체 행 삭제
DELETE FROM 소유자, 테이블 WHERE 조건; => 테이블의 조건절에 해당하는 행만 삭제
DELETE FROM hr.emp; => transaction 시작 시점
SELECT*FROM hr.emp;
ROLLBACK; => transaction 시작 시점까지 취소, transaction 종료
DELETE FROM hr.emp;
DELETE FROM hr.emp WHERE id = 2;
COMMIT;
SQL> /
ID NAME DAY
1 홍길동 23/03/28
■ 테이블 복제 CTAS
(예시1)
CREATE TABLE hr.emp
AS
SELECT*FROM hr.employees;
DESC hr.emp;
▽▽▽ 결과창
이름 널? 유형
EMPLOYEE_ID NUMBER(6)
FIRST_NAME VARCHAR2(20)
LAST_NAME NOT NULL VARCHAR2(25)
EMAIL NOT NULL VARCHAR2(25)
PHONE_NUMBER VARCHAR2(20)
HIRE_DATE NOT NULL DATE
JOB_ID NOT NULL VARCHAR2(10)
SALARY NUMBER(8,2)
COMMISSION_PCT NUMBER(2,2)
MANAGER_ID NUMBER(6)
DEPARTMENT_ID NUMBER(4)
SELECT*FROM hr.emp;
DROP TABLE hr.emp PURGE;
(예시2)
CREATE TABLE hr.emp
AS
SELECT employee_id as id, last_name||' '||first_name name, salary sal, department_id dept_id
FROM hr.employees;
desc hr.emp;
이름 널? 유형
ID NUMBER(6)
NAME VARCHAR2(46)
SAL NUMBER(8,2)
DEPT_ID NUMBER(4)
CREATE TABLE hr.emp
AS
SELECT employee_id as id, lower(last_name||' '||first_name) as name, salary*12 as sal, department_id as dept_id
FROM hr.employees;
● 테이블 생성시에 tablespace를 지정하지 않으면 유저 생성시 DEFAULT TABLESPACE로 지정된 tablespace에 저장됨(절대 system에 저장되면 안 됨 건드리면 안 됨)
=> SELECT*FROM user_users; 여기서 확인
desc hr.emp;
SELECT*FROM hr.emp;
CREATE TABLE hr.emp
TABLESPACE users
AS
SELECT employee_id as id, lower(last_name||' '||first_name) as name, salary*12 as sal, department_id as dept_id
FROM hr.employees;
(예시3)
CREATE TABLE hr.emp
AS
SELECT *
FROM hr.employees
WHERE 1 = 2; => 아무 false 값 입력: 테이블 구조만 복제, 데이터는 가져오지 않음
desc hr.emp;
SELECT*FROM hr.emp;
❍ INSERT SUBQUERY
SELECT*FROM hr.emp; => 뼈대 있음
SELECT*FROM hr.employees; => 이걸 hr.emp로 행들만 옮기고 싶음(이행)
INSERT INTO hr.emp
SELECT*FROM hr.employees;
다른 테이블 복제하고자 할 때,
1) 테이블이 없다면 = CTAS
2) 테이블이 있다면 = insert subquery 사용 (INSERT INTO)
● sys password 잊어버린 경우
1) sql developer로 접속 불가
2) run command line 창에서 conn / as sysdba 엔터!
3) alter user sys identified by 1234; (비밀번호 수정!)
● insa 화면을 처음 켰다!
1) 시스템 권한을 확인
SELECT*FROM session_privs;
▽▽▽(결과창)
PRIVILEGE
CREATE SESSION
2) 테이블 생성 원할시, 1)과 함께 테이블스페이스 확인
SELECT*FROM user_ts_quotas;
3) 테이블 생성 해 봄(권한 없음
CREATE TABLE insa.test(id number);
▽▽▽(결과창)
오류 보고 -
ORA-01031: insufficient privileges
01031. 00000 - "insufficient privileges“
4) sys에서 insa에게 테이블 만들기 권한 부여
GRANT CREATE TABLE TO insa; => sys에서 작성
5) insa에서 테이블 만들기
CREATE TABLE insa.test(id number)TABLESPACE users; => 저장될 스페이스 작성
6) 테이블 확인하기
SELECT*FROM user_tables;
▽▽▽(결과창)
TEST USERS VALID 10 1 255 655 ... ...
[문제93] insa 유저는 hr.employees 테이블을 복제해 주세요.(CTAS 사용)
테이블 생성할 수 있는 권한 확인, CREATE TABLE 시스템권한 확인
SELECT*FROM session_privs;
테이블스페이스 사용할 수 있는 권한 확인, default tablespace 확인
SELECTFROM user_ts_quotas;
SELECTFROM user_users;
subquery에서 사용해야 할 테이블의 권한 확인
SELECT*FROM user_tab_privs;
[insa]
CREATE TABLE insa.employees
AS
SELECT*FROM hr.employees;
▽▽▽(결과창)
오류 보고 -
ORA-00942: table or view does not exist
00942. 00000 - "table or view does not exist"
=> insa가 hr에 접속할 권한이 없음
[dba-sys]
GRANT SELECT ON hr.employees TO insa;
SELECT*FROM dba_tab_privs WHERE grantee = 'insa';
[insa]
SELECT*FROM user_tab_privs;
CREATE TABLE insa.employees
AS
SELECT*FROM hr.employees;
SELECT*FROM insa.employees; => 테이블 보임
[문제94] mgr 테이블 생성해주세요.
컬럼 데이터타입
id number(2)
name varchar2(30)
day date
CREATE TABLE mgr(
id number(2),
name varchar2(30),
day date default sysdate)
TABLESPACE users;
desc insa.mgr;
[문제95] hr.employees 테이블에 있는 데이터 중에 관리자 사원들의 employee_id, last_name, hire_date를 insa.mgr 테이블의 데이터를 이행(insert subquery)해 주세요.
INSERT INTO insa.mgr(id,name,day)
SELECT employee_id, last_name, hire_date
FROM hr.employees e
WHERE EXISTS (SELECT 'x'
FROM employees
WHERE manager_id = e.employee_id);
COMMIT;
SELECT*FROM insa.mgr;
((update subquery 연습용 테이블 생성))
CREATE TABLE hr.emp(
id number,
name varchar2(60),
dept_id number,
dept_name varchar2(30))
TABLESPACE users;
desc hr.emp
INSERT INTO hr.emp(id, name)
SELECT employee_id, last_name||' '||first_name
FROM hr.employees;
commit;
▽▽▽(결과창)
ID NAME DEPT_ID DEPT_NAME
100 King Steven (null) (null)
101 Kochhar Neena (null) (null)
❍ UPDATE SUBQUERY
UPDATE hr.emp
SET name = null
WHERE id = 100; => 100번 사원의 이름 null로 변경
commit;
SELECT*FROM hr.emp;
SELECT last_name||' '||first_name FROM hr.employees WHERE employee_id = 100;
UPDATE hr.emp
SET name = (SELECT last_name||' '||first_name FROM hr.employees WHERE employee_id = 100); => 전체 사원 정보 수정됨
SELECT*FROM hr.emp;
UPDATE hr.emp
SET name = (SELECT last_name||' '||first_name FROM hr.employees WHERE employee_id = 100)
WHERE id = 100;
SELECT*FROM hr.emp;
● 부서아이디를 hr에서 데이터 가져오기
SELECT department_id FROM hr.employees WHERE employee_id = 100;
UPDATE hr.emp
SET dept_id = 90
WHERE id = 102;
★correlated subquery를 이용한 update(많이 사용함)
UPDATE hr.emp e
SET dept_id = (SELECT department_id
FROM employees
WHERE employee_id = e.id)
SELECT*FROM hr.emp;
[문제96] hr.emp 테이블의 dept_name 컬럼의 값을 hr.departments 테이블의 department_name의 값을 이용해서 수정해주세요.
UPDATE hr.emp e
SET dept_name = (SELECT department_name
FROM departments
WHERE department_id = e.dept_id);
SELECT*FROM hr.emp;
commit;
❍ DELETE SUBQUERY
SELECT *
FROM hr.emp
WHERE id IN (SELECT employee_id
FROM hr.employees
WHERE hire_date < to_date('2003/01/01','yyyy/mm/dd'));
SELECT *
FROM hr.emp e
WHERE EXISTS (SELECT 'x'
FROM hr.employees
WHERE hire_date < to_date('2003/01/01','yyyy/mm/dd')
AND employee_id = e.id);
=> 2001, 2002년 입사자 행 확인
DELETE FROM hr.emp
WHERE id IN (SELECT employee_id
FROM hr.employees
WHERE hire_date < to_date('2003/01/01','yyyy/mm/dd'));
DELETE FROM hr.emp e
WHERE EXISTS (SELECT 'x'
FROM hr.employees
WHERE hire_date < to_date('2003/01/01','yyyy/mm/dd')
AND employee_id = e.id); => 내가 한 것, 이거 맞음
DELETE FROM hr.emp e
WHERE EXISTS (SELECT employee_id => 의미 없음, 문제 되지 않음
FROM hr.employees
WHERE hire_date < to_date('2003/01/01','yyyy/mm/dd')
AND employee_id = e.id);
=> 2001, 2002년 입사자 행 삭제(8개 행 삭제)
ROLLBACK;
DELETE FROM hr.emp e
WHERE EXISTS(SELECT 'x'
FROM job_history
WHERE employee_id = e.id);
ROLLBACK;
■ 자동 COMMIT 발생할 때 (정말 주의주의주의 해야 함)
SELECT * FROM hr.emp; => 107개 행 있다~
DELETE FROM hr.emp; -- transaction 시작
CREATE TABLE hr.test(id number); -- CREATE에는 COMMIT이 내부에 숨겨져 있음
ROLLBACK; (AUTO-COMMIT)
SELECT * FROM hr.emp; => 107개 행 없다!
● 테이블 생성시 딕셔너리 테이블들에 영향, 그러므로 auto commit 실행 됨
SELECT FROM user_tables;
SELECT FROM user_objects;
SELECT * FROM user_ts_quotas;
■ 자동 ROLLBACK 발생할 때