[7월 18일 점심시간 문제] 다음의 서브쿼리를 with 절로 변경하세요.
select substr(address, 1, 3 ) 주소, count(*)
from emp17
group by substr(address, 1, 3 )
having count(*) > ( select avg( count(*) )
from emp17
group by subsgtr(address, 1, 3 ) ) ;
⬇️
with address_cnt as ( select substr(address, 1,3) 주소, count(*) as cnt
from emp17
group by substr(address, 1,3) )
select 주소, cnt
from address_cnt
where cnt > ( select avg(cnt)
from address_cnt ) ;

기출문제 모델링X 긴거X

🟥 권한의 종류
문제 654. (객체권한) 내가 가지고 있는 유저 리스트가 뭐가 있는지 c## 으로 시작하는 유저이름을 조회하시오
select * from dba_users where username like 'C##%' ;
문제 655. (객체권한)
c##king2 라는 유저를 생성하고 connect 할 수 있는 권한만 부여하시오create user c##king2 identified by tiger; grant connect to c##king2;
문제 656. (객체권한)
c##king2 유저에게 c##scott 유저의 emp 테이블을
select, update, delete, insert, merge 할 수 있는 권한을 부여하시오grant select, update, delete, insert, alter on emp to c##king2 or grant all on emp to c##king2;✔️ merge 는 insert + update 라서 저거 두개 있으면 따로 안넣어도됨
문제 657. (객체권한)
c##king2 유저로 접속해서 c##scott 유저의 emp 테이블을 select 하시오connect c##king2/tiger select * from c##scott.emp;✔️public synonym 등록해놔야 그냥 emp 만 써도 조회된다.
문제 658. (객체권한)
c##scott 유저에서 c##king2 유저에게 c##scott 유저의 dept 테이블을
select, delete 할 수 있는 권한을 주시오grant select, delete on dept to c##king2;
문제 659. (객체권한)
c##king2 유저로 접속해서 c##scott 유저의 dept테이블의
부서번호 10번의 부서위치를 seoul 로 변경하시오update dept set loc='seoul' where deptno = 10;
문제 660. (객체권한)
c##king2 유저에서 c##scott의 dept 테이블을 delete 하시오delect from dept;
문제 661. (객체권한)
c##scott 유저에서 salgrade 테이블에 대해서 select 할 수 있는 권한을 db에 있는 모든 유저들에게 다 부여하시오grant select on salgrade to public;✔️ 모든 계정들에게 권한이 들어감!
✔️ public 으로 전체 주는건 주의해서 사용해야함 (오라클에서 권장 X)
현업에서는 public 사용을 자제하고 계정별로 개별적으로 부여하는게 바람직하다.
✅ 모든 컬럼에 대해서 update 할 수 있는 권한
grant update on employees to demo;
✅ 특정컬럼만 선택해서 update 할 수 있게
grant update (department_name, location_id) -> 컬럼명
on dept -> 테이블이름
to demo, manager; -> role 이름, 유저이름
➡️ 권한을 줄 수 있는 권한
c##scott c##king3 c##king4
select * from c##scott.emp;
create user c##king3 identified by tiger;
create user c##king4 identified by tiger;
grant connect to c##king3, c##king4;
grant select on emp to c##king3 with grant option;
➡️ king3 로 접속한다음에 king4 한테 select 권한 부여가능
select * from c##scott.emp;
grant select on c##scott.emp to c##king4;
🔎 c##scott 유저가 c##king3에게 준 권한을 회수한다면 king4는?
revoke select on emp from c##king3

-> 제일 처음 준 사람한테만 (king3) 회수해도 나머지 다 같이 (king4) 회수된다.
❗with grant option 을 써서 권한을 부여하고,
내가 권한을 줬던 계정의 권한을 회수하면 나머지 계정도 다같이 회수가 되는 것

✔️ 테이블권한 먼저주기
c##scott 유저에서 c##king4 유저에게 create table 권한을 줍니다.
grant create table to c##king4;
grant select on emp to c##king4;
grant update on emp to c##king4;
select * from session_privs;

❗user_tab_privs_recd 기억해놓기
col table_name for a10
col grantor for a10
col privilege for a15
(가로 길이 정해주는?)
select table_name, grantor, privilege
from user_tab_privs_recd;

✅ user_xxx : 내가 소유한 객체에 대한 정보
✅ all_xxx : 내가 소유한 객체 + 권한을 받은 객체에 대한 정보
문제 662. (객체권한)
dba 인 c##scott 이 db감사를 준비해야해서 db에 있는 유저들에 대해서 어떠한 객체 권한이 부여되었는지 엑셀로 정리해서 뽑아내야하는 업무가 생겼습니다. 어떻게 해야 효율적으로 할 수 있을까요
- 고급dba -> SQL+파이썬+PL/SQL 사용해서 자동으로 뽑아냅니다.
- 초급DBA -> SQL을 단발성으로 쿼리해서 하나씩 결과를 뽑아서 복사해서 엑셀에 수기로 입력
➡️ 개발자들이 dba 인 나에게 자주 물어보는 질문들이 뭔지 평상시 노트하고,
관련 쿼리를 목차로 만들어서 정리해놓고 파이썬, 리눅스 쉘, PL/SQL 등을 이용해서 자동화 해놓고 빠르게 알려줄 수 있도록 합니다.
revoke
revoke select on emp from c##king4;
객체권한 유저명
revoke create table from c##king4;
시스템권한 유저명
문제 663. c##scott 유저에서 c##king4 유저에게 부여된 객체 권한을 확인하고 전부 revoke 시키시오
(sql developer 에서 c##scott 유저로 조회)select table_name, grantor, grantee, privilege from all_tab_privs_made where grantor='C##SCOTT';
➡️ c##scott 유저가 부여한 모든 권한들이 나옴select table_name, grantor, grantee, privilege from all_tab_privs_made where grantee='C##KING4';
➡️ KING4 에 부여된 객체권한만 나옴revoke select on emp from c##king4; revoke update on emp from c##king4;revoke 완료~
문제 664. c##scott 유저가 public 으로 부여한 객체 권한들을 전부 revoke 시키시오
select table_name, grantor, grantee, privilege from all_tab_privs_made where grantee='PUBLIC'; revoke select on salgrade from public;✔️ 데이터 보안을 위해서 public 으로 준 권한들은 회수하는게 바람직합니다.
(공공기관 dba 는 필수. 네이버카카오토스당근쿠팡등은 보안 ISO 인증을 받으려면 이런 권한 관리에 대한 서류를 제출해야 하는데 이떄 위의 작업이 필요합니다.)
관련 OCP 문제.
grant all on emp, dept to c##king2;;❌
grant all on emp to c##king2; grant all on dept to c##king2;이렇게 따로 줘야! = 답d
- grant create table to user1, user2 이렇게 두명 동시에 주는건 되나방
시스템 권한을 주는데 맞는거 고르기A. on 은 안넣어도됨 ❌
B. alter table 은 객체권한이라 ❌
C. 유저 두명에게 동시에 줄수 있다 ⭕
D. all 아니고 public 사용임 ❌
SQL200제 (257p)
FLASHBACK QUERY
특정 테이블의 과거의 데이터를 확인할 때 사용하는 쿼리문 (특정 시점의 데이터)
예제 1. 현재 시간을 확인합니다.
select systimestamp from dual;
예제 2. emp 테이블을 전부 delete 하시오
delete from emp; commit;커밋까지 해벌임
예제 3. emp 테이블의 데이터가 지워지기전 10분전의 상태를 확인하시오
select * from emp as of timestamp (to_timestamp('2023/07/18:14:00:00','RRRR/MM/DD:HH24:MI:SS');✔️ 시간은 2시가 아니라 14시로 적어야하고, HH24 로 형태 적어줘야한다.
select * from emp as of timestamp (systimestamp - interval '10' minute);✔️ 밑에도 확인은 가능하나,시간은 계속 변하기 때문에 명확한 시간을 짚을 수 없다.
✅ 시간을 통해 테이블 복구
예제 4. emp 테이블을 '2023/07/18:14:00:00' 시간으로 복구하시오
- 먼저, emp 테이블을 flachback 이 가능한 상태로 변경한다.
alter table emp enable row movement ;
- emp 테이블을 2023/07/18:14:00:00 으로 flashback 시킵니다.
flashback table emp to timestamp to_timestamp('2023/07/18:14:00:00', 'RRRR/MM/DD:HH24:MI:SS');
문제 665. DEPT 테이블에 dname 컬럼을 전부 null 로 변경하고 commit 하시오
update dept set dname=null; commit;
문제 666. dept 테이블에 dname 에 data 가 있었던 시점으로해서 flashback query 를 하시오
✔️ 먼저 n분전 데이터 검색해본다
select * from dept as of timestamp to_timestamp('23/07/18:14:10:27','RR/MM/DD:HH24:MI:SS');
문제 607. dept 테이블을 '23/07/18:14:10:27' 로 flashback table 시키시오
alter table dept enable row movement ;➡️ enable 먼저 시켜주고,
select table_name, row_movement from user_tables where table_name='DEPT';
확인!flashback table dept to timestamp to_timestamp('23/07/18:14:10:27', 'RR/MM/DD:HH24:MI:SS');➡️ 복구한다!
✔️ 현업에서 사용할떄는 복구하기 전에 우녕ㅇ팀에게 특정시간에 데이터를 먼저 보여주고 이 시간으로 복구해도 되겠는지 의견을 물어보고 복구 하세여
✅ flashback table 전에 백업을 미리 해놓습니다.
create table dept_backup
as
select *
from dept
where 시간..
문제 608. emp테이블에서 KING 의 월급을 0으로 변경하시오
그리고 commit 하시오update emp set sal = 0 where ename='KING'; commit;
문제 609. 현재 시간에서 5분전에 KING의 월급을 확인하시오
select systimestamp from dual;23/07/18 14:30:24.591000000 +09:00
select ename, sal from emp as of timestamp to_timestamp('23/07/18 14:24:57','RR/MM/DD HH24:MI:SS') where ename='KING';5분전의 킹의 월급이 나온다
예제2.
emp 테이블의 sal 에 인덱스를 생성하시오create index emp_sal on emp(sal);
예제3.
emp 테이블을 전부 지우고 commit 합니다delete from emp; commit;
❓테이블이 지워진줄 모르고 다른 유저들이 insert 를 한다면..?

insert 는 되긴하나, 실제로 들어가거나 확인되지는 않는다.
예제4.
현재 시점에서 5분전으로 emp 테이블을 flashback 하시오select systimestamp from dual;23/07/18 14:55:25.911000000 +09:00
alter table emp enable row movement;select * from emp as of timestamp to_timestamp('23/07/18 14:47:25','RR/MM/DD HH24:MI:SS');떄는 insert 된 jane 이 뜨지 않아서, 일단 백업은 해둔다. (52분껄로)
create table emp_backup7 as select * from emp as of timestamp to_timestamp('23/07/18 14:52:25','RR/MM/DD HH24:MI:SS');⬇️ 그리고 47분 테이블로 flashback 시킨다.
select * from emp as of timestamp to_timestamp('23/07/18 14:47:25','RR/MM/DD HH24:MI:SS');
예제 6.
백업밥ㄷ은 emp_backup7 에 있는 데이터를 emp 테이블에 입력하시오insert into emp select * from emp_backup7
문제 610.
위와같이 flashback table 로 복구했는데 emp 테이블에 걸려있는 인덱스는 어떻게 되었는지 확인하시오select index_name from user_indexes where table_name='EMP';⬇️ STATUS 확인
select index_name, status from user_indexes where table_name='EMP';
테이블을 DROP 했을 때 복구하는 방법입니다.
예제 1.
EMP 테이블에 걸려있는 인덱스를 확인하세요select index_name, status from user_indexes where table_name='EMP';
예제 2. emp 테이블을 drop 하시오
drop table emp;
예제3. emp 테이블에 걸려있는 인덱스를 다시 확인하시오
-> 사라졌다.✔️ 테이블을 drop 하면 index 도 삭제된다. (+제약도)
예제 4. 휴지통 속에 emp 테이블이 있는지 확인합니다.
show recyclebin; 혹은 select * from user_recyclebin;
예제 5. 휴지통 속에 있는 emp 테이블을 복구하시오
flashback table emp to before drop;
예제 6. emp테이블에 걸려있던 인덱스를 확인하시오
select index_name from user_indexes where table_name='EMP';
✔️ 휴지통속에서 빠져나온 테이블의 인덱스는 이름이 이상해진다.
어느 컬럼의 인덱스인지 알수가 없다.
예제 7. 위의 이상해진 인덱스가 어느 컬럼에 걸린 인덱스인지 확인합니다.
select index_name, column_name from user_ind_columns where table_name='EMP';
컬럼이름 사전을 통해 sal 인덱스라는 것을 알 수 있다!
예제 8. 인덱스의 이름을 원래의 이름으로 변경하시오
alter index "BIN$icD6Vnx5QZCBddf7+yN6FQ==$0" rename to emp_sal;✔️ 만약 휴지통에서 테이블을 복구했다면, 테이블과 관련한 인덱스 이름들을 위와같이 변경해주어야 합니다.
문제 611. 휴지통을 비우시오
purge recyclebin; show recyclebin;
✅ 휴지통 안거치고 바로 지우기 (잘 안씀)
문제 612. 이 상태에서 emp 테이블을 drop 하시오
purge 옵션 사용 : 휴지통속에 안들어가고 아예 지워지는것drop table emp purge;
- 진짜 쓸데없고 지워도 되는 아주 큰 대용량 테이블을 drop 할때 사용
❗특정테이블이 그동안 어떻게 변경되어 왔는지 그 이력정보를 확인하는 쿼리문
먼저 현재 시간을 확인합니다.
select systimestamp from dual;-> 23/07/18 15:50:58.254000000 +09:00
현재 scn 번호를 확인합니다.
scn 번호란 ? system change number 의 약자로, commit 할 때 부여하는 번호
select current_scn from v$database;실행할때마다 바뀜
scn 가지고 시간 확인하기 / 시간 가지고 scn 확인하기
select scn_to_timestamp('3180430') from dual;
select timestamp_to_scn('23/07/18 15:50:58') from dual;
✔️ 아까 시간 가지고 테이블 복구 했었는데, scn 번호를 가지고도 복구할 수 있다.
(복구할 때는 scn 번호로 하는게 더 복구가 잘된다.)
emp 테이블의 KING 의 월급을 9000으로 변경하시오
update emp set sal = 9000 where ename='KING'; commit;
emp 테이블의 KING 의 부서번호를 30번으로 수정하시오
update emp set deptno = 30 where ename='KING';
emp 테이블의 KING 의 데이터를 지우시오
delete from emp where ename='KING';
emp 테이블의 KING 의 데이터가 그동안 어떻게 변경되어 왔는지 그 이력정보를 확인하시오
select ename, sal, deptno, versions_starttime, versions_endtime, versions_operation from emp versions between timestamp to_timestamp('23/07/18 15:50:58', 'RR/MM/DD HH24:MI:SS' ) and maxvalue where ename='KING';
23/07/18 15:57:53 로 가보면 KING 의 원래 데이터를 볼 수 있게따!
맨 아래에 나온 시간에 10초전 시간의 KING 의 데이터를 flashback query 로 확인하시오
select * from emp as of timestamp to_timestamp('23/07/18 15:57:43' , 'RR/MM/DD HH24:MI:SS' ) where ename='KING';
데이터 확인 가능
문제 613. '23/07/18 15:57:43' 으로 emp 테이블을 flashback table 하시오
alter table emp enable row movement;flashback table emp to timestamp to_timestamp('23/07/18 15:57:43','RR/MM/DD HH24:MI:SS');
❗특정 테이블에 대해서 그동안 변경해왔던 이력정보를 가지고
다시 과거로 되돌리기 위한 DML문 을 보여주는 쿼리문
SQL200제 책 265p 참고.
(실습이 어려움 - DB내리고, 아카이브모드로 바꾸고.. 등등)
이 작업은 DB 관리 단원에서 flashback database 배울 때 진행하도록 하겠습니다.
✏️ 책 내용 참고해서 보기!!
OCP 문제.
a. 트리거 : emp 변경되면 emp_backup 도 변경되게 하는 옵션(?)같은거. drop ❌
b. 데이터 지워지면 공간 유지 되지 않는다. ❌
c. truncate 롤백 ㄴㄴ ❌
d. truncate 해도 제약은 유지된다. ⭕
e. 데이터지워지고 공간회수 해 가지만, index 는 남아있다. ⭕
f. truncate 하면 flashback table 되지 않는다. ❌
문제 613. (SQL 마지막 문제)
emp 테이블을 truncate 하고 emp 테이블을 10분전으로 flashback table 해보시오truncate table emp; alter table emp enable row movement; flashback table emp to timestamp to_timestamp('23/07/18 16:25:43','RR/MM/DD HH24:MI:SS');
정보가 많아서 도움이 많이 됐습니다.