SQLite용 명령줄 쉘
SQLite용 명령줄 쉘 (Command Line Shell For SQLite)
SQLite 프로젝트는 사용자가 SQLite 데이터베이스에 대해 SQL 문을 대화형으로 실행할 수 있게 해주는 sqlite3(Windows에서는 sqlite3.exe)라는 명령줄 프로그램을 제공해요. 이 문서는 sqlite3 프로그램 사용법에 대한 간략한 소개를 담고 있습니다.
출처: 문서
본문
1. 시작하기
SQLite 프로젝트는 사용자가 SQLite 데이터베이스에 대해 SQL 문을 대화형으로 실행할 수 있게 해주는 sqlite3(Windows에서는 sqlite3.exe)라는 명령줄 프로그램을 제공해요. 이 문서는 sqlite3 프로그램 사용법에 대한 간략한 소개예요.
1.1. SQLite 명령줄 프로그램 대 SQLite 라이브러리
SQLite 라이브러리는 SQL 데이터베이스 엔진을 구현하는 코드예요. "sqlite3" 명령줄 프로그램 또는 "CLI"는 사용자 입력을 받아 평가를 위해 SQLite 라이브러리로 전달하는 애플리케이션이에요. 이 둘은 서로 다른 것임을 이해하세요. 누군가 "SQLite"나 "sqlite3"이라고 하면 그것은 SQLite 라이브러리 자체를 말하거나, 라이브러리에 대한 인간 인터페이스를 제공하는 CLI를 말할 수 있어요. 이 둘 중 정확히 어느 것을 말하는지 파악하려면 컨텍스트가 필요한 경우가 많아요.
이 문서는 기반이 되는 SQLite 라이브러리가 아니라 CLI에 관한 거예요.
1.2. CLI의 GUI 대안
sqlite3 프로그램은 핵심 SQLite 개발자들이 작성했고 그들을 위해 만들어졌으며, SQLite 데이터베이스 파일에 대화형으로 접근하는 공식 지원 방식이에요. 하지만 일부 사용자는 그래픽 사용자 인터페이스(GUI)를 선호할 수도 있어요. 제3자가 제공하는 그런 프로그램이 여러 개 있어요.
1.3. CLI 시작
명령 프롬프트에서 "sqlite3"을 입력해 sqlite3 프로그램을 시작하고, 선택적으로 SQLite 데이터베이스(또는 ZIP 아카이브)를 담은 파일 이름을 뒤에 붙여요. 이름이 지정된 파일이 없으면 해당 이름의 새 데이터베이스 파일이 자동으로 생성돼요. 명령줄에 데이터베이스 파일이 지정되지 않으면 일시적인 인메모리 데이터베이스가 사용돼요. 이 인메모리 데이터베이스는 프로그램이 종료될 때 삭제돼요.
시작 시 sqlite3 프로그램은 간단한 배너 메시지를 보여준 다음 SQL 입력을 요구해요. SQL 문(세미콜론으로 끝나는)을 입력하고 "Enter"를 누르면 SQL이 실행돼요.
예를 들어 "ex1.db"라는 단일 테이블 "tbl1"이 있는 새 SQLite 데이터베이스를 만들려면 이렇게 해요:
$ sqlite3 ex1.db
SQLite version 3.36.0 2021-06-18 18:36:39
Enter ".help" for usage hints.
sqlite> create table tbl1(one text, two int);
sqlite> insert into tbl1 values('hello!',10),('goodbye',20);
sqlite> select * from tbl1;
┌───────────┬─────┐
│ one │ two │
├───────────┼─────┤
│ 'hello!' │ 10 │
│ 'goodbye' │ 20 │
└───────────┴─────┘
sqlite>
시스템의 End-Of-File 문자(보통 Control-D)를 입력해 sqlite3 프로그램을 종료해요. 오래 실행되는 SQL 문을 중지하려면 인터럽트 문자(보통 Control-C)를 사용해요.
각 SQL 명령 끝에 세미콜론을 입력하는 것을 꼭 잊지 마세요! sqlite3 프로그램은 SQL 명령이 완료된 때를 알기 위해 세미콜론을 찾아요. 세미콜론을 생략하면 sqlite3는 계속 프롬프트를 주고 SQL 명령을 완료하기 위해 더 많은 텍스트를 입력하길 기다려요. 이 기능 덕분에 여러 줄에 걸친 SQL 명령을 입력할 수 있어요. 예를 들어:
sqlite> CREATE TABLE tbl2 (
...> f1 varchar(30) primary key,
...> f2 text,
...> f3 real
...> );
sqlite>
1.4. Windows에서 더블클릭 시작
Windows 사용자는 sqlite3.exe 아이콘을 더블클릭해 명령줄 쉘이 SQLite를 실행하는 터미널 창을 띄우게 할 수 있어요. 하지만 더블클릭은 명령줄 인자 없이 sqlite3.exe를 시작하므로 데이터베이스 파일이 지정되지 않아서, SQLite는 세션이 종료될 때 삭제되는 일시적인 인메모리 데이터베이스를 사용할 거예요. 영구 디스크 파일을 데이터베이스로 사용하려면 터미널 창이 시작된 직후 ".open" 명령을 입력해요:
SQLite version 3.36.0 2021-06-18 18:36:39
Enter ".help" for usage hints.
Connected to a transient in-memory database.
Use ".open FILENAME" to reopen on a persistent database.
sqlite> .open ex1.db
sqlite>
위 예제는 "ex1.db"라는 데이터베이스 파일이 열려 사용되게 해요. "ex1.db" 파일은 이전에 존재하지 않으면 생성돼요. 파일이 생각하는 디렉터리에 있도록 전체 경로명을 사용하고 싶을 거예요. 디렉터리 구분자 문자로 슬래시를 사용해요. 다시 말해 "c:\work\ex1.db"가 아니라 "c:/work/ex1.db"를 사용해요.
또는 기본 임시 저장소로 새 데이터베이스를 만든 다음 ".save" 명령으로 그 데이터베이스를 디스크 파일에 저장할 수 있어요:
SQLite version 3.36.0 2021-06-18 18:36:39
Enter ".help" for usage hints.
Connected to a transient in-memory database.
Use ".open FILENAME" to reopen on a persistent database.
sqlite> ... many SQL commands omitted ...
sqlite> .save ex1.db
sqlite>
".save" 명령을 사용할 때는 같은 이름의 기존 데이터베이스 파일을 확인 없이 덮어쓰므로 주의해요. ".open" 명령과 마찬가지로 모호함을 피하려면 슬래시 디렉터리 구분자가 있는 전체 경로명을 사용하는 게 좋아요.
1.5. 웹 브라우저에서 CLI 실행
CLI를 Emscripten으로 컴파일해 웹 브라우저 안에서 실행할 수 있어요. https://sqlite.org/fiddle에서 최근 CLI 버전을 실험해볼 수 있어요. 웹 브라우저 탭은 범용 컴퓨터가 아니므로 CLI의 모든 기능이 "fiddle"에서 사용 가능한 것은 아니에요. 하지만 "fiddle"을 SQL 명령을 시험해보는 샌드박스로 사용할 수 있어요.
2. 특수 명령 (dot-commands)
대부분의 경우 sqlite3는 SQL 입력 줄을 읽어 평가를 위해 SQLite 라이브러리로 전달해요. 하지만 점(".")으로 시작하는 입력 줄은 sqlite3 프로그램 자체가 가로채서 해석해요. 이 "dot 명령"들은 보통 쿼리의 출력 형식을 바꾸거나 특정 사전 패키징된 쿼리 문을 실행하는 데 사용돼요. 원래 dot 명령은 몇 개뿐이었지만 수년에 걸쳐 많은 새 기능이 누적되어 오늘날에는 60개가 넘어요.
사용 가능한 dot 명령 목록은 인자 없이 ".help"를 입력하면 돼요. 또는 TOPIC에 대한 자세한 정보는 ".help TOPIC"을 입력해요. SQLite 3.52.0 버전의 사용 가능한 dot-command 목록은 다음과 같아요:
sqlite> .help
.archive ... Manage SQL archives
.auth ON|OFF Show authorizer callbacks
.backup ?DB? FILE Backup DB (default "main") to FILE
.bail on|off Stop after hitting an error. Default OFF
.cd DIRECTORY Change the working directory to DIRECTORY
.changes on|off Show number of rows changed by SQL
.check GLOB Fail if output since .testcase does not match
.clone NEWDB Clone data into NEWDB from the existing database
.connection [close] [#] Open or close an auxiliary database connection
.crlf ?on|off? Whether or not to use \r\n line endings
.databases List names and files of attached databases
.dbconfig ?op? ?val? List or change sqlite3_db_config() options
.dbinfo ?DB? Show status information about the database
.dbtotxt Hex dump of the database file
.dump ?OBJECTS? Render database content as SQL
.echo on|off Turn command echo on or off
.eqp on|off|full|... Enable or disable automatic EXPLAIN QUERY PLAN
.excel Display the output of next command in spreadsheet
.exit ?CODE? Exit this program with return-code CODE
.expert EXPERIMENTAL. Suggest indexes for queries
.explain ?on|off|auto? Change the EXPLAIN formatting mode. Default: auto
.filectrl CMD ... Run various sqlite3_file_control() operations
.fullschema ?--indent? Show schema and the content of sqlite_stat tables
.help ?-all? ?PATTERN? Show help text for PATTERN
.import FILE TABLE Import data from FILE into TABLE
.imposter INDEX TABLE Create imposter table TABLE on index INDEX
.indexes ?TABLE? Show names of indexes
.intck ?STEPS_PER_UNLOCK? Run an incremental integrity check on the db
.limit ?LIMIT? ?VAL? Display or change the value of an SQLITE_LIMIT
.lint OPTIONS Report potential schema issues.
.load FILE ?ENTRY? Load an extension library
.log FILE|on|off Turn logging on or off. FILE can be stderr/stdout
.mode ?MODE? ?OPTIONS? Set output mode
.nonce STRING Suspend safe mode for one command if nonce matches
.nullvalue STRING Use STRING in place of NULL values
.once ?OPTIONS? ?FILE? Output for the next SQL command only to FILE
.open ?OPTIONS? ?FILE? Close existing database and reopen FILE
.output ?FILE? Send output to FILE or stdout if FILE is omitted
.parameter CMD ... Manage SQL parameter bindings
.print STRING... Print literal STRING
.progress N Invoke progress handler after every N opcodes
.prompt MAIN CONTINUE Replace the standard prompts
.quit Stop interpreting input stream, exit if primary.
.read FILE Read input from FILE or command output
.recover Recover as much data as possible from corrupt db.
.restore ?DB? FILE Restore content of DB (default "main") from FILE
.save ?OPTIONS? FILE Write database to FILE (an alias for .backup ...)
.scanstats on|off|est Turn sqlite3_stmt_scanstatus() metrics on or off
.schema ?PATTERN? Show the CREATE statements matching PATTERN
.session ?NAME? CMD ... Create or control sessions
.sha3sum ... Compute a SHA3 hash of database content
.shell CMD ARGS... Run CMD ARGS... in a system shell
.stats ?ARG? Show stats or turn stats on or off
.system CMD ARGS... Run CMD ARGS... in a system shell
.tables ?TABLE? List names of tables matching LIKE pattern TABLE
.timeout MS Try opening locked tables for MS milliseconds
.timer on|off Turn SQL timer on or off
.trace ?OPTIONS? Output each SQL statement as it is run
.unmodule NAME ... Unregister virtual table modules
.version Show source, library and compiler versions
.vfsinfo ?AUX? Information about the top-level VFS
.vfslist List all available VFSes
.vfsname ?AUX? Print the name of the VFS stack
.www Display output of the next command in web browser
sqlite>
".help"가 보여주는 dot-command 외에도 테스트용으로 쓰이는 문서화되지 않은 명령과 하위 호환성을 위해 유지되는 deprecated 명령이 있어요.
대부분의 dot-command는 축약할 수 있어요. 예를 들어 ".q"는 ".quit"의 흔한 축약형이에요.
3. dot-command, SQL 등에 대한 규칙
3.1. 줄 구조
CLI의 입력은 다음의 혼합 시퀀스예요:
- SQL 문
- dot-commands
- CLI 주석
SQL 문은 자유 형식이고 여러 줄에 걸칠 수 있으며 공백이나 SQL 주석이 어디든 내장될 수 있어요. SQL 문은 입력 줄 끝의 ';' 문자, 또는 그 자체로 한 줄에 있는 '/' 문자나 "go"라는 단어로 종료돼요. 입력 줄 끝에 있지 않을 때 ';' 문자는 SQL 문을 구분하는 역할을 해요. 종료 목적에서 후행 공백은 무시돼요.
dot-command는 특정 문법을 가져요:
- dot-command는 선행 공백 없이 왼쪽 여백에 "."으로 시작해야 해요.
- dot-command는 단일 입력 줄에 완전히 포함되어야 해요.
- dot-command는 일반 SQL 문 중간에 올 수 없어요. 다시 말해 계속 프롬프트에서 dot-command가 발생할 수 없어요.
- dot-command에는 주석 문법이 없어요.
- dot 명령 끝의 베어(인용되지 않은) 세미콜론은 무시돼요 (3.52.0 이후).
CLI는 '#' 문자로 시작해 줄 끝으로 확장되는 전체 줄 주석도 받아들여요. 초기 '#' 앞에 공백이 있으면 안 돼요.
3.2. Dot-command 인자
dot-command 뒤에는 0개 이상의 공백으로 구분된 인자가 올 수 있어요. 인자는 다음 규칙으로 파싱돼요:
- 후행 공백과 마지막 ";"는 (있으면) 제거돼요.
- 인자는 서로 그리고 초기 dot-command 자체와 공백으로 구분돼요.
- '...' 안의 텍스트는 텍스트에 공백이 있어도 ' 구분자가 제거된 단일 인자로 취급돼요.
- "..." 안의 텍스트는 " 구분자가 제거된 단일 인자로 취급돼요.
- C 스타일 백슬래시 이스케이프(예: \\, \n, \r, \", \033 등)는 이중 인용된 인자 안에서만 동작해요.
3.3. Dot-command는 별도로 평가돼요
dot-commands는 SQLite 라이브러리가 아니라 sqlite3.exe 명령줄 프로그램이 해석해요. 따라서 dot-commands는 sqlite3_prepare()나 sqlite3_exec() 같은 핵심 SQLite 라이브러리 인터페이스의 인자로는 동작하지 않아요.
4. 출력 형식
CLI는 SQL 쿼리 결과를 풍부한 다양한 형식으로 보여줄 수 있어요. .mode 명령이 쿼리 결과의 형식을 제어하는 데 사용돼요. .mode 명령의 동작에 대한 자세한 내용은 방대해서 별도 문서에서 다뤄요.
너무 자세히 들어가지 않고, .mode 명령이 어떻게 동작하는지 보여주는 몇 가지 빠른 예를 들어볼게요:
| .mode box | Unicode 박스 그리기 문자로 형성된 그리드로 쿼리 결과를 보여줘요. | |
|---|---|---|
| .mode quote | 쿼리 결과를 콤마로 구분된 SQL 리터럴 줄로, 출력 행당 한 줄로 보여줘요. | |
| .mode csv | 쿼리 결과를 CSV("Comma-Separated Values")로 보여줘요. | |
| .mode --list | 사용 가능한 출력 모드 목록을 보여줘요. | |
| .mode | 현재 출력 모드를 보여줘요. | |
| .mode --once box | 다음 SQL 문을 "box" 모드로 보여주지만 그 후 자동으로 현재 모드로 되돌아가요. |
5. 데이터베이스 스키마 쿼리
sqlite3 프로그램은 데이터베이스의 스키마를 보는 데 유용한 몇 가지 편의 명령을 제공해요. 이 명령들이 하는 일 중 다른 방법으로 할 수 없는 것은 없어요. 이 명령들은 순전히 단축키로 제공돼요.
예를 들어 데이터베이스의 테이블 목록을 보려면 ".tables"를 입력할 수 있어요.
sqlite> .tables
tbl1 tbl2
sqlite>
".tables" 명령은 list 모드로 설정한 다음 다음 쿼리를 실행하는 것과 비슷해요:
SELECT name FROM sqlite_schema
WHERE type IN ('table','view') AND name NOT LIKE 'sqlite_%'
ORDER BY 1
하지만 ".tables" 명령은 더 많은 일을 해요. 기본 데이터베이스뿐 아니라 모든 attached 데이터베이스에 대해 sqlite_schema 테이블을 쿼리하고, 출력을 깔끔한 컬럼으로 배열해요.
".indexes" 명령은 비슷한 방식으로 모든 인덱스를 나열해요. ".indexes" 명령에 테이블 이름인 인자가 주어지면 그 테이블의 인덱스만 보여줘요.
".schema" 명령은 데이터베이스의 완전한 스키마를 보여주거나, 선택적 탭릴네임 인자가 제공되면 단일 테이블의 스키마를 보여줘요:
sqlite> .schema
create table tbl1(one varchar(10), two smallint)
CREATE TABLE tbl2 (
f1 varchar(30) primary key,
f2 text,
f3 real
);
sqlite> .schema tbl2
CREATE TABLE tbl2 (
f1 varchar(30) primary key,
f2 text,
f3 real
);
sqlite>
".schema" 명령은 대략 list 모드로 설정한 다음 다음 쿼리를 입력하는 것과 같아요:
SELECT sql FROM sqlite_schema
ORDER BY tbl_name, type DESC, name
".tables"와 마찬가지로 ".schema" 명령은 모든 attached 데이터베이스의 스키마를 보여줘요. 단일 데이터베이스(아마 "main")의 스키마만 보고 싶다면 ".schema"에 인자를 추가해 출력을 제한할 수 있어요:
sqlite> .schema main.*
".schema" 명령은 "--indent" 옵션으로 강화될 수 있는데, 이 경우 스키마의 다양한 CREATE 문을 사람이 더 읽기 쉽도록 다시 포맷하려고 시도해요.
".databases" 명령은 현재 연결에서 열린 모든 데이터베이스 목록을 보여줘요. 항상 최소 2개가 있을 거예요. 첫 번째는 "main", 원래 열린 데이터베이스예요. 두 번째는 "temp", 임시 테이블에 사용되는 데이터베이스예요. ATTACH 문으로 attached된 데이터베이스에 대해 추가 데이터베이스가 나열될 수 있어요. 첫 번째 출력 컬럼은 데이터베이스가 attached된 이름이고, 두 번째 결과 컬럼은 외부 파일의 파일명이에요. 데이터베이스 파일이 읽기 전용이면 "'r/o'" 또는 읽기-쓰기이면 "'r/w'"인 세 번째 컬럼이 있을 수 있어요. 그리고 sqlite3_txn_state()의 결과를 보여주는 네 번째 결과 컬럼이 있을 수도 있어요.
sqlite> .databases
".fullschema" dot-command는 전체 데이터베이스 스키마를 표시한다는 점에서 ".schema" 명령처럼 동작해요. 하지만 ".fullschema"는 통계 테이블 "sqlite_stat1", "sqlite_stat3", "sqlite_stat4"의 덤프도 존재하면 포함해요. ".fullschema" 명령은 보통 특정 쿼리에 대한 쿼리 계획을 정확히 재현하는 데 필요한 모든 정보를 제공해요. SQLite 쿼리 플래너의 의심되는 문제를 보고할 때 개발자들은 문제 보고의 일부로 완전한 ".fullschema" 출력을 제공하도록 요청받아요. sqlite_stat3과 sqlite_stat4 테이블은 인덱스 항목의 샘플을 포함하므로 민감한 데이터를 포함할 수 있어서, 독점 데이터베이스의 ".fullschema" 출력을 공개 채널로 보내지 마세요.
6. 데이터베이스 파일 열기
".open" 명령은 이전에 열린 데이터베이스 명령을 먼저 닫은 후 새 데이터베이스 연결을 열어요. 가장 단순한 형태에서 ".open" 명령은 단순히 인자로 이름이 지정된 파일에 대해 sqlite3_open()을 호출해요. ":memory:"라는 이름을 사용해 CLI가 종료되거나 ".open" 명령이 다시 실행될 때 사라지는 새 인메모리 데이터베이스를 열어요. 또는 이름을 사용하지 않아 종료 시나 ".open" 사용 시 사라지는 개인용 일시적인 온디스크 데이터베이스를 열어요.
".open"에 --new 옵션이 포함되면 데이터베이스가 열리기 전에 리셋돼요. 이전 데이터는 파괴돼요. 이는 이전 데이터의 파괴적 덮어쓰기이며 확인을 요청하지 않으므로 주의해서 사용해요.
--ifexists 옵션이 포함되면 ".open" 명령은 데이터베이스 파일이 이미 존재할 때만 동작해요. 다시 말해 --ifexists는 새 빈 데이터베이스가 생성되는 것을 방지해요.
--readonly 옵션은 데이터베이스를 읽기 전용 모드로 열어요. 쓰기는 금지돼요.
--deserialize 옵션은 온디스크 파일의 전체 콘텐츠를 메모리로 읽은 다음 sqlite3_deserialize() 인터페이스를 사용해 인메모리 데이터베이스로 여는 것을 일으켜요. 물론 데이터베이스가 크면 많은 메모리가 필요할 거예요. 또한 ".save"나 ".backup" 명령으로 명시적으로 저장하지 않으면 데이터베이스에 대한 변경이 디스크에 저장되지 않아요.
--append 옵션은 SQLite 데이터베이스가 독립 파일로 동작하는 대신 기존 파일에 추가되게 해요. 자세한 내용은 appendvfs 확장을 참고해요.
--zip 옵션은 지정된 입력 파일이 SQLite 데이터베이스 파일이 아니라 ZIP 아카이브로 해석되게 해요.
--hexdb 옵션은 데이터베이스 콘텐츠가 디스크의 별도 파일이 아니라 다음 입력 줄들에서 16진수 형식으로 읽히게 해요. ".dbtotxt" dot-command 및/또는 dbtotxt 명령줄 도구를 사용해 데이터베이스에 대한 적절한 텍스트를 생성할 수 있어요. --hexdb 옵션은 SQLite 개발자가 테스트 목적으로 사용하기 위한 거예요. SQLite 내부 테스트와 개발 외에 이 옵션의 사용 사례는 알 수 없어요.
7. I/O 리다이렉트
7.1. 결과를 파일에 쓰기
기본적으로 sqlite3는 쿼리 결과를 표준 출력으로 보내요. ".output"과 ".once" 명령으로 이를 바꿀 수 있어요. .output에 인자로 출력 파일의 이름을 넣으면 이후 모든 쿼리 결과가 그 파일에 쓰여져요. 또는 .output 대신 .once 명령을 사용하면 단일 다음 명령에 대해서만 출력이 리다이렉트된 후 콘솔로 되돌아가요. 인자 없이 .output을 사용해 다시 표준 출력에 쓰기 시작해요. 예를 들어:
sqlite> .mode list --colsep "|"
sqlite> .output test_file_1.txt
sqlite> select * from tbl1;
sqlite> .exit
$ cat test_file_1.txt
hello|10
goodbye|20
$
".output" 또는 ".once" 파일명의 첫 문자가 파이프 기호("|")이면 나머지 문자는 명령으로 취급되고 출력이 그 명령으로 보내져요. 이렇게 하면 쿼리 결과를 다른 프로세스로 파이프하기가 쉬워져요. 예를 들어 Mac의 "open -f" 명령은 표준 입력에서 읽는 콘텐츠를 보여주는 텍스트 편집기를 열어요. 텍스트 편집기에서 쿼리 결과를 보려면 이렇게 입력할 수 있어요:
sqlite> .once | open -f
sqlite> SELECT * FROM bigTable;
".output"이나 ".once" 명령의 인자가 "-e"이면 출력이 임시 파일에 모아지고 시스템 텍스트 편집기가 그 텍스트 파일에서 호출돼요. 따라서 ".once -e" 명령은 ".once '|open -f'"와 같은 결과를 내지만 모든 시스템에서 이식 가능하다는 이점이 있어요.
".output"이나 ".once" 명령이 "-x" 인자를 가지면, 출력을 임시 파일에 Comma-Separated-Values(CSV)로 누적한 다음 결과에서 CSV 파일을 보는 기본 시스템 유틸리티(보통 스프레드시트 프로그램)를 호출하게 해요. 이것은 쿼리 결과를 스프레드시트로 보내 쉽게 볼 수 있는 빠른 방법이에요:
sqlite> .once -x
sqlite> SELECT * FROM bigTable;
".excel" 명령은 ".once -x"의 별칭이에요. 정확히 같은 일을 해요.
".output"이나 ".once"의 "-w" 옵션은 출력이 웹 브라우저에 표시되게 해요. ".www" 명령은 ".once -w"의 별칭이에요. 보통 웹 브라우저에 표시되는 데이터는 HTML 테이블 형태지만 "--plain" 인자를 추가해 일반 텍스트로 보여줄 수도 있어요.
sqlite> .www
sqlite> SELECT * FROM users WHERE email LIKE '%@aol.com';
7.2. 파일에서 SQL 읽기
대화형 모드에서 sqlite3는 키보드에서 입력 텍스트(SQL 문 또는 dot-commands)를 읽어요. 물론 sqlite3를 시작할 때 파일에서 입력을 리다이렉트할 수도 있지만, 그러면 프로그램과 상호작용할 수 없어요. 명령줄에서 다른 명령을 입력하면서 파일에 담긴 SQL 스크립트를 실행하는 것이 유용할 때가 있어요. 이를 위해 ".read" dot-command가 제공돼요.
".read" 명령은 (보통) 입력 텍스트를 읽을 파일 이름인 단일 인자를 받아요.
sqlite> .read myscript.sql
".read" 명령은 키보드에서 읽기를 일시 중지하고 이름이 지정된 파일에서 입력을 받아요. 파일 끝에 도달하면 입력이 키보드로 되돌아가요. 스크립트 파일은 일반 대화형 입력처럼 dot-command를 포함할 수 있어요.
".read"의 인자가 "|" 문자로 시작하면 인자를 파일로 여는 대신 인자(선행 "|" 없이)를 명령으로 실행한 다음 그 명령의 출력을 입력으로 사용해요. 따라서 SQL을 생성하는 스크립트가 있으면 다음과 유사한 명령으로 그 SQL을 직접 실행할 수 있어요:
sqlite> .read |myscript.bat
7.3. 파일 I/O 함수
명령줄 쉘은 파일에서 테이블 컬럼으로 콘텐츠를 읽고, 컬럼의 콘텐츠를 파일로 쓰는 것을 각각 용이하게 하는 두 개의 애플리케이션 정의 SQL 함수를 추가해요.
readfile(X) SQL 함수는 X라는 파일의 전체 콘텐츠를 읽고 그 콘텐츠를 BLOB로 반환해요. 테이블에 콘텐츠를 로드하는 데 사용할 수 있어요. 예를 들어:
sqlite> CREATE TABLE images(name TEXT, type TEXT, img BLOB);
sqlite> INSERT INTO images(name,type,img)
...> VALUES('icon','jpeg',readfile('icon.jpg'));
writefile(X,Y) SQL 함수는 blob Y를 X라는 파일에 쓰고 쓰여진 바이트 수를 반환해요. 이 함수를 사용해 단일 테이블 컬럼의 콘텐츠를 파일로 추출해요. 예를 들어:
sqlite> SELECT writefile('icon.jpg',img) FROM images WHERE name='icon';
readfile(X)와 writefile(X,Y) 함수는 확장 함수이며 핵심 SQLite 라이브러리에 내장되어 있지 않다는 점에 주의해요. 이 루틴들은 SQLite 소스 코드 저장소의 ext/misc/fileio.c 소스 파일에 로더블 확장으로 제공돼요.
7.4. edit() SQL 함수
CLI는 edit()이라는 또 다른 내장 SQL 함수를 가져요. Edit()은 인자를 1개 또는 2개 받아요. 첫 번째 인자는 값으로, 편집할 큰 여러 줄 문자열인 경우가 많아요. 두 번째 인자는 텍스트 편집기의 호출이에요. (편집기 동작에 영향을 주는 옵션을 포함할 수 있어요.) 두 번째 인자가 생략되면 VISUAL 환경 변수가 사용돼요. edit() 함수는 첫 번째 인자를 임시 파일에 쓰고, 임시 파일에서 편집기를 호출하고, 편집기가 끝난 후 파일을 다시 메모리로 읽어, 편집된 텍스트를 반환해요.
edit() 함수를 사용해 큰 텍스트 값을 변경할 수 있어요. 예를 들어:
sqlite> UPDATE docs SET body=edit(body) WHERE name='report-15';
이 예제에서 docs.name이 "report-15"인 엔트리의 docs.body 필드 콘텐츠가 편집기로 보내져요. 편집기가 끝나면 결과가 docs.body 필드에 다시 쓰여져요.
edit()의 기본 동작은 텍스트 편집기를 호출하는 것이에요. 하지만 두 번째 인자에 대체 편집 프로그램을 사용해 이미지나 다른 비텍스트 자원도 편집할 수 있어요. 예를 들어 테이블의 필드에 저장된 JPEG 이미지를 수정하려면 이렇게 실행할 수 있어요:
sqlite> UPDATE pics SET img=edit(img,'gimp') WHERE id='pic-1542';
edit 프로그램은 반환 값을 그냥 무시함으로써 뷰어로도 사용할 수 있어요. 예를 들어 위 이미지를 그냥 보기만 하려면 이렇게 실행할 수 있어요:
sqlite> SELECT length(edit(img,'gimp')) WHERE id='pic-1542';
7.5. CSV 또는 다른 형식 파일 가져오기
CSV(콤마 구분 값) 또는 유사하게 구분된 데이터를 SQLite 테이블로 가져오려면 ".import" 명령을 사용해요. ".import" 명령은 데이터를 읽을 소스와 데이터가 삽입될 SQLite 테이블 이름인 두 인자를 받아요. 소스 인자는 읽을 파일 이름이거나, "|" 문자로 시작하면 입력 데이터를 생성하기 위해 실행될 명령을 지정해요.
".import" 명령을 실행하기 전에 "mode"를 설정하는 것이 중요할 수 있다는 점에 주의해요. 명령줄 쉘이 입력 파일 텍스트를 파일이 구조화된 방식이 아닌 다른 형식으로 해석하려고 하지 않도록 하기 위한 신중함이에요. --csv 또는 --ascii 옵션이 사용되면 가져오기 입력 구분자를 제어해요. 그렇지 않으면 현재 출력 모드에 적용되는 구분자가 사용돼요.
"main" 스키마에 없는 테이블로 가져오려면 --schema 옵션을 사용해 테이블이 다른 스키마에 있다고 지정할 수 있어요. 이는 ATTACH'ed 데이터베이스에 유용하거나 TEMP 테이블로 가져오는 데 유용할 수 있어요.
.import가 실행될 때 첫 번째 입력 행의 처리 방식은 대상 테이블이 이미 존재하는지에 따라 달라져요. 존재하지 않으면 테이블이 자동으로 생성되고 첫 번째 입력 행의 콘텐츠가 테이블의 모든 컬럼 이름을 설정하는 데 사용돼요. 이 경우 테이블 데이터 콘텐츠는 두 번째 이후 입력 행에서 가져와요. 대상 테이블이 이미 존재하면 첫 번째 행을 포함한 입력의 모든 행이 실제 데이터 콘텐츠로 취급돼요. 입력 파일에 초기 컬럼 레이블 행이 포함되어 있으면 "--skip 1" 옵션으로 .import 명령이 그 초기 행을 건너뛰게 할 수 있어요.
예제 사용법으로, 첫 행에 컬럼 이름이 있는 CSV 파일에서 기존 임시 테이블을 로드해요:
sqlite> .import --csv --skip 1 --schema temp C:/work/somedata.csv tab1
'ascii' 외의 모드에서 입력 데이터를 읽는 동안 ".import"는 입력을 다음과 같은 예외를 제외하고 RFC 4180 스펙에 따라 필드로 구성된 레코드로 해석해요: 입력 레코드와 필드 구분자는 .mode 명령의 --rowsep 옵션과 --colsep 옵션이 설정한 것들이에요. 필드는 --ascii 모드를 제외하고는 항상 RFC 4180에 따라 수행된 인용을 되돌리는 인용 제거의 대상이 돼요. 임의 구분자와 인용 없는 데이터를 가져오려면 --ascii 옵션을 --colsep과 --rowsep 옵션과 함께 사용해 구분자를 정의해요.
7.6. CSV로 내보내기
SQLite 테이블(또는 테이블의 일부)을 CSV로 내보내려면 "mode"를 "csv"로 설정한 다음 원하는 테이블 행을 추출하는 쿼리를 실행하기만 하면 돼요. 출력은 RFC 4180에 따라 CSV로 형식 지정돼요.
sqlite> .mode csv --titles on
sqlite> .once c:/work/dataout.csv
sqlite> SELECT * FROM tab1;
sqlite> .system c:/work/dataout.csv
위 예제에서 "--titles on" 옵션은 컬럼 레이블을 첫 번째 출력 행으로 인쇄하게 해요. 즉 결과 CSV 파일의 첫 행에 컬럼 레이블이 포함된다는 뜻이에요. 컬럼 레이블이 필요하지 않으면 "--titles off"를 대신 사용해요. ("--titles off" 설정이 기본값이며, 헤더가 이전에 켜져 있지 않았다면 생략할 수 있어요.)
".once FILENAME" 줄은 모든 쿼리 출력이 콘솔에 인쇄되는 대신 이름이 지정된 파일로 가게 해요. 위 예제에서 그 줄은 CSV 콘텐츠가 "C:/work/dataout.csv"라는 파일에 쓰여지게 해요.
예제의 마지막 줄(".system c:/work/dataout.csv")은 windows에서 c:/work/dataout.csv 파일을 더블클릭하는 것과 같은 효과를 가져요. 이는 보통 CSV 파일을 표시하는 스프레드시트 프로그램을 띄워요.
그 명령은 쓰여진 그대로 Windows에서만 동작해요. Mac의 해당 줄은:
sqlite> .system open dataout.csv
Linux와 다른 unix 시스템에서는 다음과 같은 것을 입력해야 해요:
sqlite> .system xdg-open dataout.csv
7.6.1. Excel로 내보내기
스프레드시트로의 내보내기를 단순화하기 위해 CLI는 단일 쿼리의 출력을 캡처해 호스트 컴퓨터의 기본 스프레드시트 프로그램으로 보내는 ".excel" 명령을 제공해요. 이렇게 사용해요:
sqlite> .excel
sqlite> SELECT * FROM tab;
위 명령은 쿼리 출력을 CSV로 임시 파일에 쓰고, CSV 파일의 기본 처리기(보통 Excel이나 LibreOffice 같은 선호 스프레드시트 프로그램)를 호출한 다음 임시 파일을 삭제해요. 이것은 본질적으로 위에서 설명한 ".csv", ".once", ".system" 명령 시퀀스를 수행하는 단축 방법이에요.
".excel" 명령은 실제로 ".once -x"의 별칭이에요. .once의 -x 옵션은 결과를 ".csv" 접미사로 이름이 지정된 임시 파일에 CSV로 쓰고, CSV 파일의 시스템 기본 처리기를 호출하게 해요.
또한 ".once -e" 명령이 있는데, 임시 파일에 ".txt" 접미사를 붙여 기본 스프레드시트 대신 시스템의 기본 텍스트 편집기가 호출되게 한다는 점만 빼고 비슷하게 동작해요.
7.6.2. TSV(탭 구분 값)로 내보내기
필드 인용 없이 순수 TSV로 내보내려면 쿼리를 실행하기 전에 ".mode tabs"를 입력하면 돼요. 하지만 출력에 이중 인용부호 문자가 포함되면 ".import" 명령이 tabs 모드에서 그 출력을 올바르게 읽지 못할 거예요. RFC 4180에 따라 인용된 TSV를 얻어 ".import"로 tabs 모드에서 입력할 수 있게 하려면 다음을 실행해요:
.mode csv -colsep "\t"
8. ZIP 아카이브를 데이터베이스 파일로 접근
SQLite 데이터베이스 파일을 읽고 쓰는 것 외에도 sqlite3 프로그램은 ZIP 아카이브도 읽고 써요. 초기 명령줄이나 ".open" 명령에서 SQLite 데이터베이스 파일명 대신 ZIP 아카이브 파일명을 지정하기만 하면, sqlite3가 파일이 SQLite 데이터베이스가 아니라 ZIP 아카이브임을 자동 감지해 그렇게 열어요. 이는 파일 접미사와 무관하게 동작해요. 따라서 JAR, DOCX, ODP 파일과 실제로 ZIP 아카이브인 어떤 다른 파일 형식이든 열 수 있고 SQLite가 읽어줘요.
ZIP 아카이브는 다음 스키마를 가진 단일 테이블을 포함하는 데이터베이스처럼 보여요:
CREATE TABLE zip(
name, -- Name of the file
mode, -- Unix-style file permissions
mtime, -- Timestamp, seconds since 1970
sz, -- File size after decompression
rawdata, -- Raw compressed file data
data, -- Uncompressed file content
method -- ZIP compression method code
);
예를 들어 ZIP 아카이브의 모든 파일에 대해 압축 효율(원본 압축되지 않은 파일 크기에 대한 압축된 콘텐츠 크기로 표현)을 가장 압축된 것부터 가장 덜 압축된 것까지 정렬해 보고 싶다면 다음과 같은 쿼리를 실행할 수 있어요:
sqlite> SELECT name, (100.0*length(rawdata))/sz FROM zip ORDER BY 2;
또는 파일 I/O 함수를 사용해 ZIP 아카이브의 요소를 추출할 수 있어요:
sqlite> SELECT writefile(name,content) FROM zip
...> WHERE name LIKE 'docProps/%';
8.1. ZIP 아카이브 접근이 구현되는 방법
명령줄 쉘은 Zipfile 가상 테이블을 사용해 ZIP 아카이브에 접근해요. ZIP 아카이브가 열려 있을 때 ".schema" 명령을 실행하면 이를 볼 수 있어요:
sqlite> .schema
CREATE VIRTUAL TABLE zip USING zipfile('document.docx')
/* zip(name,mode,mtime,sz,rawdata,data,method) */;
파일을 열 때 명령줄 클라이언트가 파일이 SQLite 데이터베이스가 아니라 ZIP 아카이브임을 발견하면, 실제로 인메모리 데이터베이스를 열고 그 인메모리 데이터베이스 안에 ZIP 아카이브에 attached된 Zipfile 가상 테이블 인스턴스를 만들어요.
ZIP 아카이브를 열기 위한 특수 처리는 핵심 SQLite 라이브러리가 아니라 명령줄 쉘의 트릭이에요. 애플리케이션에서 ZIP 아카이브를 데이터베이스로 열려면 Zipfile 가상 테이블 모듈을 활성화한 다음 적절한 CREATE VIRTUAL TABLE 문을 실행해야 해요.
9. 전체 데이터베이스를 텍스트 파일로 변환
".dump" 명령을 사용해 데이터베이스의 전체 콘텐츠를 단일 UTF-8 텍스트 파일로 변환해요. 이 파일은 sqlite3로 다시 파이프해 데이터베이스로 변환할 수 있어요.
데이터베이스의 보관용 사본을 만드는 좋은 방법은 다음과 같아요:
$ sqlite3 ex1 .dump | gzip -c >ex1.dump.gz
이것은 나중에 또는 다른 머신에서 데이터베이스를 재구성하는 데 필요한 모든 것을 포함하는 ex1.dump.gz 파일을 생성해요. 데이터베이스를 재구성하려면 그냥 입력해요:
$ zcat ex1.dump.gz | sqlite3 ex2
텍스트 형식은 순수 SQL이므로 .dump 명령을 사용해 SQLite 데이터베이스를 다른 인기 있는 SQL 데이터베이스 엔진으로 내보낼 수도 있어요. 이렇게요:
$ createdb ex2
$ sqlite3 ex1 .dump | psql ex2
10. 손상된 데이터베이스에서 데이터 복구
".dump" 명령처럼 ".recover"는 데이터베이스 파일의 전체 콘텐츠를 텍스트로 변환하려고 시도해요. 차이점은 ".recover"가 일반 SQL 데이터베이스 인터페이스로 데이터를 읽는 대신, 가능한 한 많은 데이터베이스 페이지에서 직접 추출한 데이터를 기반으로 데이터베이스를 재조립하려고 시도한다는 거예요. 데이터베이스가 손상되었다면 ".recover"는 보통 데이터베이스의 손상되지 않은 모든 부분에서 데이터를 복구할 수 있는 반면, ".dump"는 첫 번째 손상 징후에서 멈춰요.
".recover" 명령이 어떤 데이터베이스 테이블에도 귀속시킬 수 없는 행을 하나 이상 복구하면, 출력 스크립트는 고아가 된 행을 저장하기 위해 "lost_and_found" 테이블을 만들어요. lost_and_found 테이블의 스키마는 다음과 같아요:
CREATE TABLE lost_and_found(
rootpgno INTEGER, -- root page of tree pgno is a part of
pgno INTEGER, -- page number row was found on
nfield INTEGER, -- number of fields in row
id INTEGER, -- value of rowid field, or NULL
c0, c1, c2, c3... -- columns for fields of row
);
"lost_and_found" 테이블은 데이터베이스에서 복구된 각 고아 행에 대해 하나의 행을 포함해요. 추가로, 어떤 SQL 인덱스에도 귀속될 수 없는 복구된 각 인덱스 항목에 대해 하나의 행이 있어요. SQLite 데이터베이스에서 SQL 인덱스 항목과 WITHOUT ROWID 테이블 항목을 저장하는 데 같은 형식이 사용되기 때문이에요.
| Column | Contents |
|---|---|
| rootpgno | 행을 특정 데이터베이스 테이블에 귀속시키지 못하더라도 데이터베이스 파일 내의 트리 구조의 일부일 수 있어요. 이 경우 그 트리 구조의 루트 페이지 번호가 이 컬럼에 저장돼요. 또는 행이 발견된 페이지가 트리 구조의 일부가 아니면 이 컬럼은 "pgno" 컬럼의 값, 즉 행이 발견된 페이지의 페이지 번호 사본을 저장해요. 모든 경우는 아니지만 많은 경우에서, 이 컬럼에 같은 값이 있는 lost_and_found 테이블의 모든 행은 같은 테이블에 속해요. |
| pgno | 이 행이 발견된 페이지의 페이지 번호. |
| nfield | 이 행의 필드 수. |
| id | 행이 WITHOUT ROWID 테이블에서 온 경우 이 컬럼은 NULL을 포함해요. 그렇지 않으면 그 행의 64비트 정수 rowid 값을 포함해요. |
| c0, c1, c2... | 행의 각 컬럼 값이 이 컬럼들에 저장돼요. ".recover" 명령은 가장 긴 고아 행이 요구하는 만큼 많은 컬럼으로 lost_and_found 테이블을 만들어요. |
복구된 데이터베이스 스키마에 이미 "lost_and_found"라는 테이블이 있으면 ".recover" 명령은 "lost_and_found0"이라는 이름을 사용해요. "lost_and_found0" 이름도 이미 사용 중이면 "lost_and_found1" 등을 사용해요. 기본 이름 "lost_and_found"는 ".recover"를 --lost-and-found 스위치로 호출해 덮어쓸 수 있어요. 예를 들어 출력 스크립트가 테이블을 "orphaned_rows"라고 부르게 하려면:
sqlite> .recover --lost-and-found orphaned_rows
11. 확장 로딩
".load" 명령을 사용해 런타임에 명령줄 쉘에 새 맞춤 애플리케이션 정의 SQL 함수, collating sequence, 가상 테이블, VFS를 추가할 수 있어요. 먼저 확장을 DLL 또는 공유 라이브러리로 빌드한 다음(Run-Time Loadable Extensions 문서에 설명된 대로) 입력해요:
sqlite> .load /path/to/my_extension
SQLite가 확장 파일명에 적절한 확장 접미사(windows에서는 ".dll", Mac에서는 ".dylib", 대부분의 다른 unix에서는 ".so")를 자동으로 추가한다는 점에 주의해요. 확장의 전체 경로명을 지정하는 것이 일반적으로 좋은 생각이에요.
SQLite는 확장 파일명을 기반으로 확장의 엔트리 포인트를 계산해요. 이 선택을 덮어쓰려면 ".load" 명령의 두 번째 인자로 확장 이름을 추가하기만 하면 돼요.
여러 유용한 확장의 소스 코드는 SQLite 소스 트리의 ext/misc 하위 디렉터리에서 찾을 수 있어요. 이 확장들을 있는 그대로 사용하거나, 자신의 특정 요구를 해결하기 위해 맞춤 확장을 만드는 기초로 사용할 수 있어요.
12. 데이터베이스 콘텐츠의 암호화 해시
".sha3sum" dot-command는 데이터베이스 콘텐츠의 SHA3 해시를 계산해요. 명확히 하자면, 해시는 디스크의 표현이 아니라 데이터베이스 콘텐츠에 대해 계산돼요. 즉 예를 들어 VACUUM이나 데이터를 보존하는 유사한 변환은 해시를 바꾸지 않아요.
".sha3sum" 명령은 해시에 어떤 SHA3 변형을 사용할지 정의하는 "--sha3-224", "--sha3-256", "--sha3-384", "--sha3-512" 옵션을 지원해요. 기본값은 SHA3-256이에요.
데이터베이스 스키마(sqlite_schema 테이블)는 보통 해시에 포함되지 않지만 "--schema" 옵션으로 추가할 수 있어요.
".sha3sum" 명령은 LIKE 패턴인 단일 선택적 인자를 받아요. 이 옵션이 있으면 LIKE 패턴과 일치하는 이름의 테이블만 해시돼요.
".sha3sum" 명령은 명령줄 쉘에 포함된 확장 함수 "sha3_query()"의 도움으로 구현돼요.
13. 데이터베이스 콘텐츠 자체 테스트
".selftest" 명령은 데이터베이스가 온전하고 손상되지 않았는지 확인하려고 시도해요. .selftest 명령은 스키마에서 "selftest"라는 테이블을 찾고 다음과 같이 정의돼요:
CREATE TABLE selftest(
tno INTEGER PRIMARY KEY, -- Test number
op TEXT, -- 'run' or 'memo'
cmd TEXT, -- SQL command to run, or text of "memo"
ans TEXT -- Expected result of the SQL command
);
.selftest 명령은 selftest 테이블의 행을 selftest.tno 순서로 읽어요. 각 'memo' 행에 대해 'cmd'의 텍스트를 출력에 써요. 각 'run' 행에 대해 'cmd' 텍스트를 SQL로 실행하고 결과를 'ans'의 값과 비교해, 결과가 다르면 오류 메시지를 보여줘요.
selftest 테이블이 없으면 ".selftest" 명령은 PRAGMA integrity_check를 실행해요.
".selftest --init" 명령은 selftest 테이블이 아직 없으면 만든 다음, 모든 테이블 콘텐츠의 SHA3 해시를 확인하는 항목을 추가해요. 이후 ".selftest" 실행은 데이터베이스가 어떤 식으로든 변경되지 않았는지 검증할 거예요. 테이블 부분집합이 변경되지 않았음을 검증하는 테스트를 생성하려면 ".selftest --init"을 실행한 다음 상수가 아닌 테이블을 참조하는 selftest 행을 DELETE하면 돼요.
14. SQLite Archive 지원
".archive" dot-command와 "-A" 명령줄 옵션은 SQLite Archive 형식에 대한 내장 지원을 제공해요. 인터페이스는 unix 시스템의 "tar" 명령과 비슷해요. ".ar" 명령의 각 호출은 단일 명령 옵션을 지정해야 해요. ".archive"에 사용 가능한 명령은 다음과 같아요:
| Option | Long Option | Purpose |
|---|---|---|
| -c | --create | 지정된 파일을 포함하는 새 아카이브를 만들어요. |
| -x | --extract | 아카이브에서 지정된 파일을 추출해요. |
| -i | --insert | 기존 아카이브에 파일을 추가해요. |
| -r | --remove | 아카이브에서 파일을 제거해요. |
| -t | --list | 아카이브의 파일을 나열해요. |
| -u | --update | 변경된 경우 기존 아카이브에 파일을 추가해요. |
명령 옵션뿐 아니라 ".ar"의 각 호출은 하나 이상의 수정자 옵션을 지정할 수 있어요. 일부 수정자 옵션은 인자를 요구하고, 일부는 그렇지 않아요. 사용 가능한 수정자 옵션은 다음과 같아요:
| Option | Long Option | Purpose |
|---|---|---|
| -v | --verbose | 각 파일이 처리될 때 나열해요. |
| -f FILE | --file FILE | 지정되면 FILE을 아카이브로 사용해요. 그렇지 않으면 현재 "main" 데이터베이스가 작업할 아카이브라고 가정해요. |
| -a FILE | --append FILE | --file처럼 FILE을 아카이브로 사용하되, apndvfs VFS를 사용해 파일을 열어 FILE이 이미 존재하면 아카이브가 FILE 끝에 추가되게 해요. |
| -C DIR | --directory DIR | 지정되면 모든 상대 경로를 현재 작업 디렉터리 대신 DIR에 상대적인 것으로 해석해요. |
| -g | --glob | glob(Y,X)를 사용해 인자를 아카이브의 이름과 매칭해요. |
| -n | --dryrun | 아카이브 작업을 수행하기 위해 실행될 SQL을 보여주지만 실제로는 아무것도 변경하지 않아요. |
| -- | -- | 이후의 모든 명령줄 단어는 옵션이 아니라 명령 인자예요. |
명령줄 사용을 위해 "-A" 바로 뒤에, 공백 없이 짧은 스타일 명령줄 옵션을 추가해요. 이후 모든 인자는 .archive 명령의 일부로 간주돼요. 예를 들어 다음 명령은 동등해요:
sqlite3 new_archive.db -Acv file1 file2 file3
sqlite3 new_archive.db ".ar -cv file1 file2 file3"
긴 스타일과 짧은 스타일 옵션은 섞을 수 있어요. 예를 들어 다음은 동등해요:
-- Two ways to create a new archive named "new_archive.db" containing
-- files "file1", "file2" and "file3".
.ar -c --file new_archive.db file1 file2 file3
.ar -f new_archive.db --create file1 file2 file3
또는 ".ar" 다음의 첫 번째 인자는 모든 필수 옵션의 짧은 형태를 ("-" 문자 없이) 연결한 것일 수 있어요. 이 경우 인자를 요구하는 옵션의 인자는 명령줄에서 다음에 읽혀지고, 남은 단어는 명령 인자로 간주돼요. 예를 들어:
-- Create a new archive "new_archive.db" containing files "file1" and
-- "file2" from directory "dir1".
.ar cCf dir1 new_archive.db file1 file2 file3
14.1. SQLite Archive 생성 명령
새 아카이브를 만들고 기존 아카이브(현재 "main" db 또는 --file 옵션이 지정한 파일)를 덮어써요. 옵션 뒤의 각 인자는 아카이브에 추가할 파일이에요. 디렉터리는 재귀적으로 가져와져요. 예제는 위를 참고해요.
14.2. SQLite Archive 추출 명령
아카이브에서 파일을 추출해요(현재 작업 디렉터리 또는 --directory 옵션이 지정한 디렉터리로). 인자와 이름이 일치하는 파일이나 디렉터리(--glob 옵션의 영향을 받아)가 추출돼요. 또는 옵션 뒤에 인자가 없으면 모든 파일과 디렉터리가 추출돼요. 지정된 디렉터리는 재귀적으로 추출돼요. 지정된 이름이나 매칭 패턴을 아카이브에서 찾을 수 없으면 오류예요.
-- Extract all files from the archive in the current "main" db to the
-- current working directory. List files as they are extracted.
.ar --extract --verbose
-- Extract file "file1" from archive "ar.db" to directory "dir1".
.ar fCx ar.db dir1 file1
-- Extract files with ".h" extension to directory "headers".
.ar -gCx headers *.h
14.3. SQLite Archive 목록 명령
아카이브의 콘텐츠를 나열해요. 인자가 지정되지 않으면 모든 파일이 나열돼요. 그렇지 않으면 --glob 옵션의 영향을 받아 인자와 일치하는 것만 나열돼요. 현재 --verbose 옵션은 이 명령의 동작을 바꾸지 않아요. 그것은 미래에 바뀔 수 있어요.
-- List contents of archive in current "main" db..
.ar --list
14.4. SQLite Archive 삽입 및 업데이트 명령
--update와 --insert 명령은 시작 전에 현재 아카이브를 삭제하지 않는다는 점만 빼고 --create 명령처럼 동작해요. 파일의 새 버전은 같은 이름의 기존 파일을 조용히 대체하지만, 그 외에는 아카이브의 초기 콘텐츠(있으면)가 그대로 유지돼요.
--insert 명령의 경우 나열된 모든 파일이 아카이브에 삽입돼요. --update 명령의 경우 파일이 이전에 아카이브에 존재하지 않거나, "mtime"이나 "mode"가 현재 아카이브에 있는 것과 다를 때만 삽입돼요.
호환성 참고: SQLite 3.28.0 (2019-04-16) 이전에는 --update 옵션만 지원됐는데, 그 옵션은 변경되었는지 여부와 무관하게 항상 모든 파일을 다시 삽입한다는 점에서 --insert처럼 동작했어요.
14.5. SQLite Archive 제거 명령
--remove 명령은 --glob 옵션의 영향을 받아 제공된 인자(있으면)와 일치하는 파일과 디렉터리를 삭제해요. 아카이브에서 아무것도 매칭하지 않는 인자를 제공하는 것은 오류예요.
14.6. ZIP 아카이브에 대한 작업
FILE이 SQLite Archive가 아니라 ZIP 아카이브여도 ".archive" 명령과 "-A" 명령줄 옵션은 여전히 동작해요. 이것은 zipfile 확장을 사용해 이루어져요. 따라서 다음 명령은 출력 형식만 다르고 대략 동등해요:
| 전통적 명령 | 동등한 sqlite3.exe 명령 |
|---|---|
| unzip archive.zip | sqlite3 -Axf archive.zip |
| unzip -l archive.zip | sqlite3 -Atvf archive.zip |
| zip -r archive2.zip dir | sqlite3 -Acf archive2.zip dir |
14.7. SQLite Archive 작업을 구현하는 데 사용되는 SQL
다양한 SQLite Archive 명령은 SQL 문을 사용해 구현돼요. 애플리케이션 개발자는 적절한 SQL을 실행해 자신의 프로젝트에 SQLite Archive 읽기/쓰기 지원을 쉽게 추가할 수 있어요.
SQLite Archive 작업을 구현하는 데 어떤 SQL 문이 사용되는지 보려면 --dryrun 또는 -n 옵션을 추가해요. 이렇게 하면 SQL이 표시되지만 SQL 실행은 억제돼요.
SQLite Archive 작업을 구현하는 데 사용되는 SQL 문은 다양한 로더블 확장을 사용해요. 이 확장들은 모두 SQLite 소스 트리의 ext/misc/ 하위 폴더에서 제공돼요. 완전한 SQLite Archive 지원에 필요한 확장은 다음과 같아요:
-
fileio.c — 이 확장은 디스크의 파일에서 콘텐츠를 읽고 쓰는 SQL 함수 readfile()과 writefile()을 추가해요. fileio.c 확장은 디렉터리 콘텐츠를 나열하는 fsdir() 테이블-값 함수와, stat() 시스템 호출의 숫자 st_mode 정수를 "ls -l" 명령 방식으로 사람이 읽을 수 있는 문자열로 변환하는 lsmode() 함수도 포함해요.
-
sqlar.c — 이 확장은 SQLite Archive에서 콘텐츠가 삽입되고 추출될 때 파일 콘텐츠를 압축하고 압축 해제하는 데 필요한 sqlar_compress()와 sqlar_uncompress() 함수를 추가해요.
-
zipfile.c — 이 확장은 ZIP 아카이브를 읽는 데 사용되는 "zipfile(FILE)" 테이블-값 함수를 구현해요. 이 확장은 SQLite 아카이브 대신 ZIP 아카이브를 읽을 때만 필요해요.
-
appendvfs.c — 이 확장은 SQLite 데이터베이스를 실행 파일 같은 다른 파일에 추가할 수 있게 하는 새 VFS를 구현해요. 이 확장은 .archive 명령의 --append 옵션을 사용할 때만 필요해요.
15. SQL 파라미터
SQLite는 리터럴 값이 허용되는 SQL 문의 어느 곳에든 바인딩된 파라미터가 나타날 수 있게 해줘요. 이 파라미터의 값은 sqlite3_bind_...() API 계열로 설정돼요.
파라미터는 이름이 있거나 없을 수 있어요. 이름 없는 파라미터는 단일 물음표("?")예요. 이름 있는 파라미터는 숫자가 바로 뒤따르는 "?"(예: "?15" 또는 "?123") 또는 "$", ":", "@" 문자 중 하나 다음에 영숫자 이름이 오는 것(예: "$var1", ":xyz", "@bingo")이에요.
이 명령줄 쉘은 이름 없는 파라미터를 바인딩되지 않은 채로 두는데, 이는 SQL NULL 값을 가질 것이라는 뜻이에요. 하지만 이름 있는 파라미터는 값이 할당될 수 있어요. "sqlite_parameters"라는 TEMP 테이블이 다음과 같은 스키마로 존재하면:
CREATE TEMP TABLE sqlite_parameters(
key TEXT PRIMARY KEY,
value
) WITHOUT ROWID;
그리고 그 테이블의 key 컬럼이 파라미터 이름(초기 "?", "$", ":", "@" 문자 포함)과 정확히 일치하는 엔트리가 있으면, 파라미터는 value 컬럼의 값이 할당돼요. 엔트리가 없으면 파라미터는 NULL로 기본 설정돼요.
".parameter" 명령은 이 테이블 관리를 단순화하기 위해 존재해요. ".parameter init" 명령(보통 ".param init"으로 축약)은 temp.sqlite_parameters 테이블이 아직 없으면 만들어요. ".param list" 명령은 temp.sqlite_parameters 테이블의 모든 엔트리를 보여줘요. ".param clear" 명령은 temp.sqlite_parameters 테이블을 드롭해요. ".param set KEY VALUE"와 ".param unset KEY" 명령은 temp.sqlite_parameters 테이블에서 엔트리를 만들거나 삭제해요.
".param set KEY VALUE"에 전달된 VALUE는 SQL 리터럴이거나, 값을 얻기 위해 평가될 수 있는 어떤 다른 SQL 표현식이나 쿼리일 수 있어요. 이렇게 하면 서로 다른 타입의 값을 설정할 수 있어요. 그런 평가가 실패하면 제공된 VALUE가 대신 인용되어 텍스트로 삽입돼요. 그런 초기 평가가 VALUE 콘텐츠에 따라 실패할 수도 있고 안 할 수도 있기 때문에, 텍스트 값을 얻는 확실한 방법은 그것을 위에서 설명한 명령-꼬리 파싱으로부터 보호된 단일 인용부호로 감싸는 것이에요. 예를 들어 (-1365 값을 의도하지 않는 한):
.parameter init
.parameter set @phoneNumber "'202-456-1111'"
이중 인용부호가 단일 인용부호를 보호하고 인용된 텍스트가 하나의 인자로 파싱되도록 보장한다는 점에 주의해요.
temp.sqlite_parameters 테이블은 명령줄 쉘의 파라미터에만 값을 제공해요. temp.sqlite_parameter 테이블은 SQLite C언어 API로 직접 실행되는 쿼리에는 영향이 없어요. 개별 애플리케이션은 자신의 파라미터 바인딩을 구현할 것으로 기대돼요. 명령줄 쉘 소스 코드에서 "sqlite_parameters"를 검색해 명령줄 쉘이 파라미터 바인딩을 어떻게 하는지 보고, 직접 구현하는 방법에 대한 힌트로 사용할 수 있어요.
16. 인덱스 추천 (SQLite Expert)
참고: 이 명령은 실험적이에요. 미래 어느 시점에 제거되거나 인터페이스가 호환되지 않는 방식으로 수정될 수 있어요.
대부분의 비자명한 SQL 데이터베이스에서 성능의 핵심은 올바른 SQL 인덱스를 만드는 것이에요. 여기서 "올바른 SQL 인덱스"는 애플리케이션이 최적화해야 하는 쿼리가 빠르게 실행되게 하는 인덱스를 의미해요. ".expert" 명령은 데이터베이스에 있으면 특정 쿼리를 돕는 인덱스를 제안함으로써 이를 지원할 수 있어요.
".expert" 명령이 먼저 발행되고, 그다음 별도 줄에 SQL 쿼리가 와요. 예를 들어 다음 세션을 고려해보세요:
sqlite> CREATE TABLE x1(a, b, c); -- Create table in database
sqlite> .expert
sqlite> SELECT * FROM x1 WHERE a=? AND b>?; -- Analyze this SELECT
CREATE INDEX x1_idx_000123a7 ON x1(a, b);
0|0|0|SEARCH TABLE x1 USING INDEX x1_idx_000123a7 (a=? AND b>?)
sqlite> CREATE INDEX x1ab ON x1(a, b); -- Create the recommended index
sqlite> .expert
sqlite> SELECT * FROM x1 WHERE a=? AND b>?; -- Re-analyze the same SELECT
(no new indexes)
0|0|0|SEARCH TABLE x1 USING INDEX x1ab (a=? AND b>?)
위에서 사용자는 데이터베이스 스키마(단일 테이블 "x1")를 만들고, ".expert" 명령으로 쿼리, 이 경우 "SELECT * FROM x1 WHERE a=? AND b>?"를 분석해요. 쉘 도구는 사용자가 새 인덱스(인덱스 "x1_idx_000123a7")를 만들 것을 추천하고 쿼리가 EXPLAIN QUERY PLAN 형식으로 사용할 계획을 출력해요. 사용자는 그다음 동등한 스키마의 인덱스를 만들고 같은 쿼리에 대해 분석을 다시 실행해요. 이번에는 쉘 도구가 새 인덱스를 추천하지 않고, 기존 인덱스가 주어졌을 때 SQLite가 쿼리에 사용할 계획을 출력해요.
".expert" 명령은 다음 옵션을 받아요:
| Option | Purpose |
|---|---|
| ‑‑verbose | 있으면 분석된 각 쿼리에 대해 더 자세한 보고를 출력해요. |
| ‑‑sample PERCENT | 이 파라미터는 기본적으로 0으로, ".expert" 명령이 쿼리와 데이터베이스 스키마만으로 인덱스를 추천하게 해요. 이는 사용자가 데이터 분포 통계를 생성하기 위해 ANALYZE 명령을 데이터베이스에 실행하지 않았을 때 SQLite 쿼리 플래너가 쿼리용 인덱스를 선택하는 방식과 비슷해요. 이 옵션에 0이 아닌 인자가 전달되면 ".expert" 명령은 각 데이터베이스 테이블에 현재 저장된 행의 PERCENT 퍼센트를 기반으로 고려되는 모든 인덱스에 대해 유사한 데이터 분포 통계를 생성해요. 특이한 데이터 분포를 가진 데이터베이스의 경우, 특히 애플리케이션이 ANALYZE를 실행하려는 경우 더 나은 인덱스 추천으로 이어질 수 있어요. 작은 데이터베이스와 현대 CPU에서는 "--sample 100"을 전달하지 않을 이유가 보통 없어요. 하지만 큰 데이터베이스 테이블에서는 데이터 분포 통계 수집이 비쌀 수 있어요. 작업이 너무 느리면 --sample 옵션에 더 작은 값을 전달해보세요. |
이 절에서 설명한 기능은 SQLite expert 확장 코드를 사용해 다른 애플리케이션이나 도구에 통합될 수 있어요.
확장 로드 메커니즘을 통해 제공되는 SQL 커스텀 함수를 통합한 데이터베이스 스키마는 .expert 기능과 함께 작동하도록 특별한 준비가 필요할 수 있어요. 이 기능은 기능을 구현하기 위해 추가 연결을 사용하므로, 그 커스텀 함수는 그 추가 연결에서도 사용 가능해야 해요. 이것은 Automatically Load Statically Linked Extensions와 Persistent Loadable Extensions에서 설명하는 확장 로드/사용 옵션으로 할 수 있어요.
17. 여러 데이터베이스 연결로 작업
버전 3.37.0 (2021-11-27)부터 CLI는 한 번에 여러 데이터베이스 연결을 열 수 있어요. 한 번에 하나의 데이터베이스 연결만 활성화돼요. 비활성 연결은 여전히 열려 있지만 유휴 상태예요.
".connection" dot-command(보통 ".conn"으로 축약)를 사용해 데이터베이스 연결 목록과 현재 어떤 것이 활성인지 표시를 확인해요. 각 데이터베이스 연결은 0에서 9 사이의 정수로 식별돼요. (동시에 최대 10개 연결을 열 수 있어요.) ".conn" 명령 다음에 그 번호를 입력해 다른 데이터베이스 연결로 전환하고, 없으면 만들어요. ".conn close N"(N은 연결 번호)을 입력해 데이터베이스 연결을 닫아요.
기반이 되는 SQLite 데이터베이스 연결은 완전히 서로 독립적이지만, 출력 형식 같은 많은 CLI 설정은 모든 데이터베이스 연결에서 공유돼요. 따라서 한 연결에서 출력 모드를 바꾸면 모두에서 바뀌어요. 반면 .open 같은 일부 dot-command는 현재 연결에만 영향을 줘요.
18. 기타 확장 기능
CLI는 SQLite 라이브러리에 포함되지 않은 여러 SQLite 확장으로 빌드돼요. 몇 개는 앞 절들에서 설명하지 않은 기능을 추가해요. 즉:
- 텍스트에 내장된 부호 없는 정수를 다른 텍스트와 함께 그 값에 따라 정렬하는 UINT collating sequence.
- decimal 확장이 제공하는 소수점 산술.
- generate_series() 테이블-값 함수.
- blob를 base64 또는 base85 텍스트로 인코딩하거나 같은 것을 blob로 디코딩하는 base64()와 base85() 함수.
- REGEXP 연산자에 바인딩된 POSIX 확장 정규 표현식 지원.
19. 다른 Dot Commands
명령줄 쉘에서 사용할 수 있는 다른 많은 dot-command가 있어요. 특정 버전과 빌드의 SQLite에 대한 완전한 목록은 ".help" 명령을 참고해요.
20. 셸 스크립트에서 sqlite3 사용
셸 스크립트에서 sqlite3을 사용하는 한 가지 방법은 "echo"나 "cat"을 사용해 파일에 일련의 명령을 생성한 다음, 생성된 명령 파일에서 입력을 리다이렉트하며 sqlite3을 호출하는 거예요. 이는 잘 동작하고 많은 상황에서 적절해요. 하지만 추가 편의로, sqlite3는 데이터베이스 이름 뒤의 두 번째 인자로 단일 SQL 명령이 명령줄에 입력되는 것을 허용해요. sqlite3 프로그램이 두 인자로 시작되면 두 번째 인자가 SQLite 라이브러리로 전달되어 처리되고, 쿼리 결과는 list 모드로 표준 출력에 인쇄되며 프로그램이 종료돼요. 이 메커니즘은 "awk" 같은 프로그램과 함께 sqlite3을 사용하기 쉽게 설계됐어요. 예를 들어:
$ sqlite3 ex1 'select * from tbl1' \
> | awk '{printf "<tr><td>%s<td>%s\n",$1,$2 }'
<tr><td>hello<td>10
<tr><td>goodbye<td>20
$
21. SQL 문의 끝 표시
SQLite 명령은 보통 세미콜론으로 끝나요. CLI에서 "GO"라는 단어(대소문자 무시)나 그 자체로 한 줄에 있는 슬래시 문자 "/"를 사용해 명령을 끝낼 수도 있어요. 이들은 각각 SQL Server와 Oracle이 사용하며, 호환성을 위해 SQLite CLI가 지원해요. CLI가 이 입력을 SQLite 코어로 전달하기 전에 세미콜론으로 변환하므로 sqlite3_exec()에서는 동작하지 않아요.
22. CLI 시작 방법에 대한 더 많은 세부 사항
앞서 말했듯 CLI를 시작하는 일반적인 방법은 데이터베이스 파일 이름 뒤에 "sqlite3"을 입력하는 것이에요. 하지만 "sqlite3" 프로그램은 데이터베이스 파일명 외에도 많은 다른 인자를 받아요.
22.1. 추가 명령줄 인자
데이터베이스 파일명 뒤에 나타나는 추가 명령줄 인자는 입력 텍스트 줄인 것처럼 취급돼요. 각 추가 인자는 SQL 문이나 dot-command일 수 있어요. 왼쪽에서 오른쪽으로 순서대로 평가돼요. SQLite 문과 dot-command 모두 흔히 공백을 포함하므로, 각 SQL 문이나 dot-command를 (OS에 따라) 단일 또는 이중 인용부호 안에 넣어야 할 거예요. 예를 들어:
$ sqlite3 test.db ".mode box" "SELECT * FROM users;"
이렇게 추가 인자가 제공되면 표준 입력은 읽히지 않고 CLI는 모든 추가 인자를 처리한 후 종료해요.
22.2. 명령줄 옵션
"-" 문자로 시작하는 추가 인자는 명령줄 옵션이에요. 사용 가능한 명령줄 옵션이 많아요. --help 명령줄 옵션을 사용해 목록을 보세요:
$ sqlite3 --help
FILENAME is the name of an SQLite database. A new database is created
if the file does not previously exist. Defaults to :memory:.
OPTIONS include:
-- treat no subsequent arguments as options
-A ARGS... run ".archive ARGS" and exit
-append append the database to the end of the file
-ascii set output mode to 'ascii'
-bail stop after hitting an error
-batch force batch I/O
-box set output mode to 'box'
-column set output mode to 'column'
-cmd COMMAND run "COMMAND" before reading stdin
-csv set output mode to 'csv'
-deserialize open the database using sqlite3_deserialize()
-echo print inputs before execution
-escape T ctrl-char escape; T is one of: symbol, ascii, off
-init FILENAME read/process named file
-[no]header turn headers on or off
-heap SIZE Size of heap for memsys3 or memsys5
-help show this message
-html set output mode to HTML
-ifexists only open if database already exists
-interactive force interactive I/O
-json set output mode to 'json'
-line set output mode to 'line'
-list set output mode to 'list'
-lookaside SIZE N use N entries of SZ bytes for lookaside memory
-markdown set output mode to 'markdown'
-maxsize N maximum size for a --deserialize database
-memtrace trace all memory allocations and deallocations
-mmap N default mmap size set to N
-newline SEP set output row separator. Default: '\n'
-nofollow refuse to open symbolic links to database files
-nonce STRING set the safe-mode escape nonce
-no-rowid-in-view Disable rowid-in-view using sqlite3_config()
-nullvalue TEXT set text string for NULL values. Default ''
-pagecache SIZE N use N slots of SZ bytes each for page cache memory
-pcachetrace trace all page cache operations
-quote set output mode to 'quote'
-readonly open the database read-only
-safe enable safe-mode
-separator SEP set output column separator. Default: '|'
-stats print memory stats before each finalize
-table set output mode to 'table'
-tabs set output mode to 'tabs'
-unsafe-testing allow unsafe commands and modes for testing
-version show SQLite version
-vfs NAME use NAME as the default VFS
-vfstrace enable tracing of all VFS calls
-zip open the file as a ZIP Archive
CLI는 명령줄 옵션 형식에 대해 유연해요. 하나 또는 두 개의 선행 "-" 문자가 허용돼요. 따라서 "-box"와 "--box"는 같은 뜻이에요. 명령줄 옵션은 왼쪽에서 오른쪽으로 처리돼요. 따라서 "--box" 옵션은 이전 "--quote" 옵션을 덮어써요.
대부분의 명령줄 옵션은 설명이 필요 없지만, 몇 가지는 아래에서 추가 논의할 가치가 있어요.
22.3. --safe 명령줄 옵션
--safe 명령줄 옵션은 명령줄에 이름이 지정된 특정 데이터베이스 파일에 대한 변경 외에 호스트 컴퓨터에 어떤 변경도 일으킬 수 있는 CLI의 모든 기능을 비활성화하려고 시도해요. 아이디어는 알 수 없거나 신뢰할 수 없는 소스에서 큰 SQL 스크립트를 받으면, --safe 옵션을 사용해 익스플로잇의 위험 없이 그 스크립트가 무엇을 하는지 보기 위해 실행할 수 있다는 거예요. --safe 옵션은 (다른 것들 중에서) 다음을 비활성화해요:
- .open 명령 — --hexdb 옵션이 사용되거나 파일명이 ":memory:"인 경우 제외. 이것은 스크립트가 원래 명령줄에 이름이 지정되지 않은 어떤 데이터베이스 파일도 읽거나 쓰지 못하게 해요.
- ATTACH SQL 명령.
- edit(), fts3_tokenizer(), load_extension(), readfile(), writefile() 같은 잠재적으로 유해한 부작용이 있는 SQL 함수.
- .archive 명령.
- .backup과 .save 명령.
- .import 명령.
- .load 명령.
- .log 명령.
- .shell과 .system 명령.
- .excel, .once, .output 명령.
- 해로운 부작용이 있을 수 있는 다른 명령.
기본적으로, 주 데이터베이스 파일 외의 디스크 파일에서 읽거나 쓰는 CLI의 모든 기능이 비활성화돼요.
22.3.1. 특정 명령에 대한 --safe 제한 우회
명령줄에 "--nonce NONCE" 옵션(어떤 크고 임의의 NONCE 문자열)도 포함되면, ".nonce NONCE" 명령(같은 큰 nonce 문자열로)이 다음 SQL 문이나 dot-command가 --safe 제한을 우회하도록 허용해요.
의심스러운 스크립트를 실행하고 싶은데 그 스크립트가 --safe가 보통 비활성화하는 기능을 하나 둘 요구한다고 가정해보세요. 예를 들어 추가 데이터베이스 하나를 ATTACH해야 한다고 가정해요. 또는 스크립트가 특정 확장을 로드해야 한다고 가정해요. 이는 (주의 깊게 감사한) ATTACH 문이나 ".load" 명령 앞에 적절한 ".nonce" 명령을 두고 "--nonce" 명령줄 옵션으로 같은 nonce 값을 제공함으로써 이루어질 수 있어요. 그러면 그 특정 명령은 정상적으로 실행될 수 있지만, 다른 모든 안전하지 않은 명령은 여전히 제한돼요.
".nonce"의 사용은 실수가 적대적 스크립트가 시스템을 손상시키도록 할 수 있다는 의미에서 위험해요. 따라서 ".nonce"는 신중하고 아껴서, --safe 모드에서 스크립트를 실행할 다른 방법이 없을 때 최후의 수단으로 사용해요.
22.4. --unsafe-testing 명령줄 옵션
--unsafe-testing 명령줄 옵션은 내부 테스트 전용으로 의도된 CLI의 기능을 활성화해요. --unsafe-testing 옵션은 SQLITE_DBCONFIG_DEFENSIVE와 SQLITE_DBCONFIG_TRUSTED_SCHEMA 같은 SQLite에 내장된 방어를 비활성화해요. --unsafe-testing 옵션은 오용하면 데이터베이스 손상, 메모리 오류, 또는 CLI 자체나 SQLite 라이브러리의 유사한 문제를 일으킬 수 있는 기능도 활성화해요. --unsafe-testing이 활성화하는 기능의 예는 assertion fault 메커니즘이 작동하는지 검증하기 위해 의도적으로 assertion fault를 트리거하는 ".testctrl assert false" 명령이에요.
--unsafe-testing 옵션의 사용을 요구하는 오작동은 일반적으로 버그로 간주되지 않아요.
22.5. --no-utf8과 --utf8 명령줄 옵션
Windows 플랫폼에서 콘솔이 입력이나 출력에 사용될 때, 콘솔에서 제공되거나 콘솔로 보내지는 문자 인코딩과 CLI의 내부 UTF-8 텍스트 표현 사이에 변환이 필요해요. CLI의 이전 버전은 최신 OS 버전에서 UTF-8을 생성하거나 받아들이게 만들 수 있는 Windows 콘솔 기능에 의존하는 변환의 사용을 활성화하거나 비활성화하는 이 옵션들을 받아들였어요.
현재 CLI 버전(3.44.1 이상)은 Windows 콘솔 API에서/로 UTF-16을 읽거나 써서 콘솔 I/O를 해요. 이것은 Windows 2000까지 거슬러 올라가는 Windows 버전에서도 올바르게 동작하므로, 더 이상 이 옵션들이 필요하지 않아요. 여전히 받아들여지지만 효과는 없어요.
모든 경우에, 콘솔이 아닌 텍스트 I/O는 UTF-8로 인코딩돼요.
비-Windows 플랫폼에서도 이 옵션들은 무시돼요.
23. 소스에서 sqlite3 프로그램 컴파일
unix 시스템과 MinGW를 사용하는 Windows에서 명령줄 쉘을 컴파일하려면, 보통의 configure-make 명령이 동작해요:
sh configure; make
configure-make는 표준 소스 트리의 정식 소스에서 빌드하든 amalgamated 번들에서 빌드하든 동작해요. 의존성은 거의 없어요. 정식 소스에서 빌드할 때는 동작하는 tclsh가 필요해요. amalgamation 번들을 사용하면 tclsh가 보통 하는 모든 전처리 작업이 이미 수행되어 일반 빌드 도구만 필요해요.
.archive 명령이 동작하려면 동작하는 zlib 압축 라이브러리가 필요해요.
MSVC를 사용하는 Windows에서는 Makefile.msc와 함께 nmake를 사용해요:
nmake /f Makefile.msc
.archive 명령의 올바른 동작을 위해 zlib 소스 코드의 사본을 소스 트리의 compat/zlib 하위 디렉터리에 만들고 이렇게 컴파일해요:
nmake /f Makefile.msc USE_ZLIB=1
23.1. 직접 빌드 (Do-It-Yourself Builds)
sqlite3 명령줄 인터페이스의 소스 코드는 "shell.c"라는 단일 파일에 있어요. shell.c 소스 파일은 다른 소스에서 생성되지만, shell.c의 대부분의 코드는 src/shell.c.in에서 찾을 수 있어요. (정식 소스 트리에서 "make shell.c"를 입력해 shell.c를 재생성해요.) shell.c 파일을(sqlite3 라이브러리 소스 코드와 함께) 컴파일해 실행 파일을 생성해요. 예를 들어:
gcc -o sqlite3 shell.c sqlite3.c -ldl -lpthread -lz -lm
완전한 기능의 명령줄 쉘을 제공하려면 다음 추가 컴파일 시 옵션이 권장돼요:
- -DSQLITE_THREADSAFE=0
- -DSQLITE_ENABLE_EXPLAIN_COMMENTS
- -DSQLITE_HAVE_ZLIB
- -DSQLITE_INTROSPECTION_PRAGMAS
- -DSQLITE_ENABLE_UNKNOWN_SQL_FUNCTION
- -DSQLITE_ENABLE_STMTVTAB
- -DSQLITE_ENABLE_DBPAGE_VTAB
- -DSQLITE_ENABLE_DBSTAT_VTAB
- -DSQLITE_ENABLE_OFFSET_SQL_FUNC
- -DSQLITE_ENABLE_JSON1
- -DSQLITE_ENABLE_RTREE
- -DSQLITE_ENABLE_FTS4
- -DSQLITE_ENABLE_FTS5