Skip to content

02 — 접속과 실행 방법 ​

🗓️ 3월 2일 (토) 저녁 · DB는 올라갔다. 이제 SQL> 프롬프트를 여는 법과 스크립트 파일을 통째로 돌리는 법을 손에 익힌다. 이 교재 전체에서 쓰는 방법은 셋뿐이고, 01화의 SQL은 전부 방법 A의 SQL>에 붙여 넣으면 된다.


0. 먼저 알아 둘 것 — sqlplus는 내 PC에 없다 ​

$ sqlplus sqlp/sqlp@localhost:1521/FREEPDB1
bash: sqlplus: command not found

당연하다. 오라클은 컨테이너 안에서 돌고 있고, sqlplus도 그 안에 있다. 내 PC에는 오라클 클라이언트를 설치한 적이 없다. 방법은 둘뿐이다. ① 컨테이너 안의 sqlplus를 빌려 쓰거나 ② 내 PC에 클라이언트를 설치하는 것이다. 이 교재는 ①을 기본으로 한다.


1. 방법 A — 컨테이너 안 sqlplus를 대화형으로 (설치 0, 가장 빠름) ★ 기본 ​

bash
docker exec -it ora-hanorder sqlplus sqlp/sqlp@localhost/FREEPDB1

SQL> 프롬프트가 뜬다. 여기에 쿼리를 붙여 넣으면 된다. 나갈 때는 EXIT를 입력한다.

Connected to:
Oracle AI Database 26ai Free Release 23.26.2.0.0 ...

SQL>

-it의 t는 터미널을 붙이라는 뜻이라서 진짜 터미널에서만 동작한다. Windows Terminal, PowerShell, CMD, Git Bash에서는 모두 된다. 스크립트 안이나 파이프 뒤에서는 안 되므로, 그때는 -i만 쓴다(§4).

들어가자마자 이 두 줄부터 친다. 그래야 표가 잘리지 않는다.

sql
SET LINESIZE 150 PAGESIZE 100
SET SERVEROUTPUT OFF        -- 실행계획(DISPLAY_CURSOR)을 볼 거면 반드시 OFF

다른 고객사: 컨테이너 이름과 계정만 바꾼다. 포트는 컨테이너 안에서 접속하는 것이라 항상 1521이고, 생략해도 된다.

bash
docker exec -it ora-burger  sqlplus dev/dev@localhost/FREEPDB1
docker exec -it ora-dist    sqlplus pup/pup@localhost/FREEPDB1
docker exec -it ora-newshop sqlplus ORA_SQL_TEST/1qaz2wsx@localhost/FREEPDB1

관리자(SYS)로 접속: 권한을 주거나 AWR을 볼 때 쓴다. OS 인증이라 비밀번호가 필요 없다.

bash
MSYS_NO_PATHCONV=1 docker exec -it ora-hanorder sqlplus / as sysdba
sql
ALTER SESSION SET CONTAINER = FREEPDB1;   -- SYS 는 CDB$ROOT 로 들어오므로 PDB 로 내려간다
SHOW CON_NAME                              -- FREEPDB1 이면 OK

16·17화의 AWR은 반대로 CDB$ROOT에 그대로 있어야 한다. 그때 다시 설명한다.

🐞 Git Bash 함정 — MSYS_NO_PATHCONV=1을 빼면 SYS 접속이 안 된다 ​

Git Bash는 인자로 들어온 /를 Windows 경로로 바꿔 버린다. 실제로 해 보면 이렇다.

$ docker exec -i ora-hanorder echo /
C:/Program Files/Git/

그래서 sqlplus -s / as sysdba의 /가 경로로 바뀌고, SQL*Plus는 접속하지 않고 사용법(Usage)만 길게 출력하고 끝난다. 에러 메시지가 ORA-로 시작하지 않아서 오라클 문제로 보이지 않는다는 점이 이 함정의 고약한 부분이다. PowerShell, CMD, WSL에는 이 변환이 없다. 그쪽에서는 MSYS_NO_PATHCONV=1 없이 그냥 쓰면 된다.

이 교재의 Git Bash 예시에는 모두 이 접두사가 붙어 있다. 직접 입력하다가 SYS 접속이 안 되면 접두사를 빠뜨리지 않았는지부터 의심해 본다. (대안: 비밀번호로 접속하면 경로 변환이 일어나지 않는다. docker exec -i ora-hanorder sqlplus -s sys/oracle@localhost/FREEPDB1 as sysdba)


2. 방법 B — SQL Developer (GUI, 구조를 그림으로 보고 싶을 때) ​

터미널이 익숙하지 않거나, ERD를 그리거나, 결과를 표로 훑어보고 싶을 때 쓴다. 오라클이 무료로 배포한다.

설치와 접속 ​

  1. https://www.oracle.com/database/sqldeveloper/에서 Windows 64-bit with JDK 11 included를 받는다(설치할 필요 없이 압축만 풀면 된다).
  2. sqldeveloper.exe를 실행하고, 왼쪽 접속(Connections) 패널에서 + 버튼을 누른다.
  3. 아래처럼 입력한다.
항목값
NameHANORDER
사용자 이름sqlp
비밀번호sqlp (저장 체크)
호스트 이름localhost
포트1521
서비스 이름FREEPDB1 ← SID가 아니다. 라디오 버튼을 "서비스 이름"에 둔다
  1. 테스트를 눌러 상태: 성공이 뜨면 접속을 누른다.

⚠️ 다른 고객사는 포트만 바꾼다(ora-burger 1522 · ora-dist 1523 · ora-newshop 1524). 접속 이름은 BURGER DIST NEWSHOP처럼 회사 이름으로 붙여 두면 헷갈리지 않는다.

실행계획 보는 두 버튼 ​

키무엇언제
F10Explain Plan: 예상 실행계획실행하지 않고 계획만 볼 때
F6Autotrace: 실제 실행 + 통계(consistent gets)튜닝 실습의 핵심 버튼. 방법 A의 SET AUTOTRACE ON과 같다

테이블 하나 살펴보기 ​

접속 트리에서 테이블 > T_ORD_BIG 항목을 더블클릭하면 탭이 열린다. 탭은 열(Columns), 데이터, 제약 조건, 색인(Indexes), 통계, SQL로 나뉜다. T_ORD_BIG의 색인 탭은 비어 있다. 01화 §5에서 이것을 눈으로 확인하고, 내장 Data Modeler로 ERD를 그려 본다(그리고 관계선이 하나도 그려지지 않는 것을 확인한다).


3. 방법 C — SQLcl (내 PC에 CLI를 두고 싶을 때) ​

자바만 있으면 되는 오라클의 현대식 커맨드라인 도구다. sqlplus 문법이 그대로 통하고, 자동완성과 히스토리 기능이 붙어 있다.

  1. Java 17 이상이 필요하다. java -version으로 확인하고, 없으면 https://adoptium.net에서 Temurin 17/21 LTS를 받는다.
  2. https://www.oracle.com/database/sqldeveloper/technologies/sqlcl/에서 zip을 받아 압축을 풀고, sqlcl\bin을 PATH에 추가한다.
  3. 접속한다. 호스트에서 접속하므로 포트를 적어야 한다.
bash
sql sqlp/sqlp@localhost:1521/FREEPDB1

SET AUTOTRACE ON과 DBMS_XPLAN.DISPLAY_CURSOR 모두 방법 A와 똑같이 동작한다.

방법 C가 없어도 이 교재는 끝까지 따라갈 수 있다. 방법 A로 시작하고, 불편해지면 그때 설치한다.


4. 스크립트 파일을 통째로 돌리기 ★ 매 화 실습이 이 형태다 ​

파일을 컨테이너로 복사할 필요 없이 stdin으로 흘려보낸다. 단계가 하나 줄고, Git Bash와 PowerShell 양쪽에서 똑같이 동작하는 것을 실측으로 확인했다.

bash
# Git Bash — 스크립트가 있는 폴더에서
docker exec -i ora-hanorder sqlplus -s sqlp/sqlp@localhost/FREEPDB1 < 어떤_스크립트.sql
powershell
# PowerShell — 창을 열 때마다 첫 줄을 한 번 (아래 ⚠️)
$OutputEncoding = New-Object System.Text.UTF8Encoding $false
Get-Content 어떤_스크립트.sql -Encoding UTF8 | docker exec -i ora-hanorder sqlplus -s sqlp/sqlp@localhost/FREEPDB1

⚠️ PowerShell 사용자는 한글이 두 번 깨질 수 있다. ① 파일을 읽을 때: -Encoding UTF8을 빼면 깨진다. ② 파이프로 docker에 넘길 때: Windows PowerShell 5.1은 기본값($OutputEncoding = ASCII)으로 한글을 모두 ?로 바꿔 보낸다. -Encoding UTF8을 붙여도 마찬가지다. 실측해 보면 SELECT '한글테스트' FROM dual;을 기본값으로 흘려보냈을 때는 ?????가 돌아오고, 위의 첫 줄을 입력한 뒤에는 한글테스트가 돌아온다. 한빛유통(ora-hanorder) 스크립트는 한글이 주석에만 있어서 데이터가 깨지지 않는다. 하지만 버거원(ora-burger)의 상품명과 매장명은 한글 데이터라서 그대로 ?로 저장된다. 매번 입력하기 번거로우면 notepad $PROFILE로 프로필을 열어 그 한 줄을 넣어 둔다. Git Bash에는 이 문제가 없다.

부분뜻
-i (-it 아님)stdin만 붙인다. 터미널(-t)을 붙이면 파이프와 충돌한다
-ssilent. 배너와 프롬프트를 찍지 않아 출력이 깨끗하다
< 파일 / Get-Content … |파일 내용을 그대로 SQL>에 타이핑하는 것과 같다. 파일 끝에서 자동 종료

왜 docker cp + @파일이 아닌가 ​

그 방식도 되지만 두 가지가 번거롭다. ① 복사 단계가 하나 더 있고, ② 이 저장소의 스크립트는 끝에 EXIT가 없어서 @파일로 돌리면 다 돌린 뒤 SQL>에서 멈춘다. 예전 문서에 있던 printf "…\nEXIT\n" | sqlplus 형태는 PowerShell에서 \n이 그대로 파일명에 붙어 깨진다. 그래서 위의 형태로 통일했다.

여러 줄 SQL을 파일 없이 즉석에서 ​

Git Bash: heredoc을 쓴다.

bash
docker exec -i ora-hanorder sqlplus -s sqlp/sqlp@localhost/FREEPDB1 <<'SQL'
SET LINESIZE 150
SELECT COUNT(*) FROM T_ORD_BIG;
SQL

PowerShell: <<'SQL'은 안 된다. 대신 here-string을 쓴다(@"와 "@는 각각 줄 맨 앞에 둔다).

powershell
@"
SET LINESIZE 150
SELECT COUNT(*) FROM T_ORD_BIG;
"@ | docker exec -i ora-hanorder sqlplus -s sqlp/sqlp@localhost/FREEPDB1

이 교재의 bash 블록에 <<'SQL'이 보이면 PowerShell 사용자는 이렇게 바꿔 읽는다. 셸을 하나로 정해 쓰면 바꿔 읽을 일도 없다.


5. 멈춘 건지 도는 건지 — 판정하는 법 ​

적재가 "오래 걸리는 것 같을" 때는 다른 셸에서 다음을 실행한다.

bash
MSYS_NO_PATHCONV=1 docker exec -i ora-hanorder sqlplus -s / as sysdba <<'SQL'
ALTER SESSION SET CONTAINER = FREEPDB1;
SELECT sid, status, event, ROUND(last_call_et) et_sec FROM v$session
 WHERE username='SQLP' AND type='USER';
SQL
STATUSEVENT뜻
INACTIVESQL*Net message from client다 끝났는데 프롬프트에서 대기 중이다(§4의 @파일 함정). EXIT를 입력해 준다
ACTIVEdb file … / log file … / direct path …진짜로 일하는 중이다. et_sec가 올라가고 있으면 기다린다

이 쿼리는 01화 1_현장_관측에서 계기판 가운데 하나로 다시 나온다. "이 세션은 지금 무엇을 기다리고 있나"는 튜너가 가장 자주 던지는 질문이다.


6. 측정 3종 세트 — 이름만 미리 알아 둔다 ​

매 화 쓰는 도구다. 읽는 법은 01화 1_현장_관측에서 배운다. 여기서는 켜지는지만 확인한다.

① 예상 실행계획: SQL을 실행하지 않고 계획만 본다.

sql
EXPLAIN PLAN FOR SELECT COUNT(*) FROM T_ORD_BIG WHERE ORD_ST = 'CANCEL';
SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY());

② 실제 실행계획 + 실측 행수·블록: 이 교재에서 주로 쓰는 도구다. E-Rows(예상)와 A-Rows(실제), Buffers(읽은 블록)를 본다.

sql
SET SERVEROUTPUT OFF
SELECT /*+ GATHER_PLAN_STATISTICS */ COUNT(*) FROM T_ORD_BIG WHERE ORD_ST = 'CANCEL';
SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY_CURSOR(FORMAT => 'ALLSTATS LAST'));

③ AUTOTRACE: 계획과 통계(consistent gets)를 한 번에 본다. SQL Developer에서는 F6이다.

sql
SET AUTOTRACE ON
SELECT COUNT(*) FROM T_ORD_BIG WHERE ORD_ST = 'CANCEL';
SET AUTOTRACE OFF
  • ②에서 ORA-01031이 나면 고객사/L1_ora-hanorder/00_측정권한_부여.sql을 돌린 뒤 다시 접속한다.
  • ②가 DBMS_OUTPUT.GET_LINES를 보여 주면 SET SERVEROUTPUT OFF로 둔다.
  • ③에서 권한 오류가 나면 SYS로 @?/sqlplus/admin/plustrce.sql을 돌린 뒤 GRANT PLUSTRACE TO sqlp;를 실행한다.

Buffers = consistent gets = 논리적 블록 읽기. 이 교재에서 "빨라졌다"는 말은 모두 이 숫자로만 한다. 윤세라의 말대로 "초로 말하지 마. 블록으로 말해."


7. 접속 정보 요약 (냉장고에 붙여 둘 표) ​

컨테이너호스트 포트계정방법 A방법 B·C (호스트에서)
ora-hanorder1521sqlp/sqlpdocker exec -it ora-hanorder sqlplus sqlp/sqlp@localhost/FREEPDB1localhost:1521/FREEPDB1
ora-burger1522dev/devdocker exec -it ora-burger sqlplus dev/dev@localhost/FREEPDB1localhost:1522/FREEPDB1
ora-dist1523pup/pupdocker exec -it ora-dist sqlplus pup/pup@localhost/FREEPDB1localhost:1523/FREEPDB1
ora-newshop1524ORA_SQL_TEST/1qaz2wsx · ecommerce/…docker exec -it ora-newshop sqlplus ORA_SQL_TEST/1qaz2wsx@localhost/FREEPDB1localhost:1524/FREEPDB1
(관리자, 전부)—/ as sysdba (OS 인증) · sys/oracle · system/oracleMSYS_NO_PATHCONV=1 docker exec -it <컨테이너> sqlplus / as sysdbasys/oracle@localhost:<포트>/FREE as sysdba

준비가 끝났다. 이제 01화로 넘어간다: 01화 · 인수인계 없는 인수인계