SQL 문장 (SQL statements)
D1에서 지원하는 SQL 문장과 PRAGMA 명령들을 다루는 문서예요. 테이블·인덱스 목록을 조회하고 스키마를 검사하는 데이터베이스 수준 문장들을 설명해요.
출처: 문서
본문
SQL statements
D1은 SQLite의 쿼리 엔진을 활용하므로 대부분의 SQLite SQL 규약과 호환돼요. D1은 테이블·인덱스를 나열하고 특정 테이블이나 인덱스의 스키마를 검사할 수 있는 여러 데이터베이스 수준 문장을 지원해요.
이 문장들은 Cloudflare 대시보드의 D1 콘솔, wrangler d1 execute, 또는 D1 Worker Bindings API를 통해 실행할 수 있어요.
지원되는 SQLite 확장 (Supported SQLite extensions)
D1은 추가 기능을 위해 SQLite 확장의 일부를 지원해요.
- 전체 텍스트 검색을 위한 FTS5 모듈 ↗︎(
fts5vocab포함). - JSON 함수와 연산자를 위한 JSON 확장 ↗︎.
- 수학 함수 (Math functions) ↗︎.
지원되는 함수의 전체 목록은 소스 코드 ↗︎를 참조하세요.
호환되는 PRAGMA 문장 (Compatible PRAGMA statements)
D1은 일부 SQLite PRAGMA ↗︎ 문장을 지원해요. PRAGMA 문장은 SQLite를 위한 SQL 확장이에요. PRAGMA 명령은 다음 용도로 사용할 수 있어요.
- 특정 SQLite 작업의 동작을 수정하기
- 스키마나 테이블에 대한 내부 데이터를 SQLite 라이브러리에 쿼리하기 (단, PRAGMA 문장은 테이블의 내용을 쿼리할 수 없어요.)
- 환경 변수를 제어하기
이 페이지의 PRAGMA 문장 예시에서는 다음 SQL을 사용해요.
PRAGMA foreign_keys=off;
DROP TABLE IF EXISTS "Employee";
DROP TABLE IF EXISTS "Category";
DROP TABLE IF EXISTS "Customer";
DROP TABLE IF EXISTS "Shipper";
DROP TABLE IF EXISTS "Supplier";
DROP TABLE IF EXISTS "Order";
DROP TABLE IF EXISTS "Product";
DROP TABLE IF EXISTS "OrderDetail";
DROP TABLE IF EXISTS "CustomerCustomerDemo";
DROP TABLE IF EXISTS "CustomerDemographic";
DROP TABLE IF EXISTS "Region";
DROP TABLE IF EXISTS "Territory";
DROP TABLE IF EXISTS "EmployeeTerritory";
DROP VIEW IF EXISTS [ProductDetails_V];
CREATE TABLE IF NOT EXISTS "Employee" ( "Id" INTEGER PRIMARY KEY, "LastName" VARCHAR(8000) NULL, "FirstName" VARCHAR(8000) NULL, "Title" VARCHAR(8000) NULL, "TitleOfCourtesy" VARCHAR(8000) NULL, "BirthDate" VARCHAR(8000) NULL, "HireDate" VARCHAR(8000) NULL, "Address" VARCHAR(8000) NULL, "City" VARCHAR(8000) NULL, "Region" VARCHAR(8000) NULL, "PostalCode" VARCHAR(8000) NULL, "Country" VARCHAR(8000) NULL, "HomePhone" VARCHAR(8000) NULL, "Extension" VARCHAR(8000) NULL, "Photo" BLOB NULL, "Notes" VARCHAR(8000) NULL, "ReportsTo" INTEGER NULL, "PhotoPath" VARCHAR(8000) NULL);
CREATE TABLE IF NOT EXISTS "Category" ( "Id" INTEGER PRIMARY KEY, "CategoryName" VARCHAR(8000) NULL, "Description" VARCHAR(8000) NULL);
CREATE TABLE IF NOT EXISTS "Customer" ( "Id" VARCHAR(8000) PRIMARY KEY, "CompanyName" VARCHAR(8000) NULL, "ContactName" VARCHAR(8000) NULL, "ContactTitle" VARCHAR(8000) NULL, "Address" VARCHAR(8000) NULL, "City" VARCHAR(8000) NULL, "Region" VARCHAR(8000) NULL, "PostalCode" VARCHAR(8000) NULL, "Country" VARCHAR(8000) NULL, "Phone" VARCHAR(8000) NULL, "Fax" VARCHAR(8000) NULL);
CREATE TABLE IF NOT EXISTS "Shipper" ( "Id" INTEGER PRIMARY KEY, "CompanyName" VARCHAR(8000) NULL, "Phone" VARCHAR(8000) NULL);
CREATE TABLE IF NOT EXISTS "Supplier" ( "Id" INTEGER PRIMARY KEY, "CompanyName" VARCHAR(8000) NULL, "ContactName" VARCHAR(8000) NULL, "ContactTitle" VARCHAR(8000) NULL, "Address" VARCHAR(8000) NULL, "City" VARCHAR(8000) NULL, "Region" VARCHAR(8000) NULL, "PostalCode" VARCHAR(8000) NULL, "Country" VARCHAR(8000) NULL, "Phone" VARCHAR(8000) NULL, "Fax" VARCHAR(8000) NULL, "HomePage" VARCHAR(8000) NULL);
CREATE TABLE IF NOT EXISTS "Order" ( "Id" INTEGER PRIMARY KEY, "CustomerId" VARCHAR(8000) NULL, "EmployeeId" INTEGER NOT NULL, "OrderDate" VARCHAR(8000) NULL, "RequiredDate" VARCHAR(8000) NULL, "ShippedDate" VARCHAR(8000) NULL, "ShipVia" INTEGER NULL, "Freight" DECIMAL NOT NULL, "ShipName" VARCHAR(8000) NULL, "ShipAddress" VARCHAR(8000) NULL, "ShipCity" VARCHAR(8000) NULL, "ShipRegion" VARCHAR(8000) NULL, "ShipPostalCode" VARCHAR(8000) NULL, "ShipCountry" VARCHAR(8000) NULL);
CREATE TABLE IF NOT EXISTS "Product" ( "Id" INTEGER PRIMARY KEY, "ProductName" VARCHAR(8000) NULL, "SupplierId" INTEGER NOT NULL, "CategoryId" INTEGER NOT NULL, "QuantityPerUnit" VARCHAR(8000) NULL, "UnitPrice" DECIMAL NOT NULL, "UnitsInStock" INTEGER NOT NULL, "UnitsOnOrder" INTEGER NOT NULL, "ReorderLevel" INTEGER NOT NULL, "Discontinued" INTEGER NOT NULL);
CREATE TABLE IF NOT EXISTS "OrderDetail" ( "Id" VARCHAR(8000) PRIMARY KEY, "OrderId" INTEGER NOT NULL, "ProductId" INTEGER NOT NULL, "UnitPrice" DECIMAL NOT NULL, "Quantity" INTEGER NOT NULL, "Discount" DOUBLE NOT NULL);
CREATE TABLE IF NOT EXISTS "CustomerCustomerDemo" ( "Id" VARCHAR(8000) PRIMARY KEY, "CustomerTypeId" VARCHAR(8000) NULL);
CREATE TABLE IF NOT EXISTS "CustomerDemographic" ( "Id" VARCHAR(8000) PRIMARY KEY, "CustomerDesc" VARCHAR(8000) NULL);
CREATE TABLE IF NOT EXISTS "Region" ( "Id" INTEGER PRIMARY KEY, "RegionDescription" VARCHAR(8000) NULL);
CREATE TABLE IF NOT EXISTS "Territory" ( "Id" VARCHAR(8000) PRIMARY KEY, "TerritoryDescription" VARCHAR(8000) NULL, "RegionId" INTEGER NOT NULL);
CREATE TABLE IF NOT EXISTS "EmployeeTerritory" ( "Id" VARCHAR(8000) PRIMARY KEY, "EmployeeId" INTEGER NOT NULL, "TerritoryId" VARCHAR(8000) NULL);
CREATE VIEW [ProductDetails_V] as select p.*, c.CategoryName, c.Description as [CategoryDescription], s.CompanyName as [SupplierName], s.Region as [SupplierRegion] from [Product] p join [Category] c on p.CategoryId = c.id join [Supplier] s on s.id = p.SupplierId;
PRAGMA table_list
데이터베이스의 테이블과 뷰를 나열해요. D1이 유지하는 시스템 테이블도 포함돼요.
반환 값 (Return values)
테이블마다 한 행씩 반환돼요. 각 행에는 다음이 포함돼요.
Schema: 테이블이 나타나는 스키마(예:main또는temp)name: 테이블의 이름type: 객체의 유형(table,view,shadow,virtual중 하나)ncol: 생성되거나 숨겨진 컬럼을 포함한 테이블의 컬럼 수wr: 테이블이 WITHOUT ROWID 테이블이면1, 아니면0strict: 테이블이 STRICT 테이블이면1, 아니면0
PRAGMA table_list 예시
npx wrangler d1 execute [DATABASE_NAME] --command='PRAGMA table_list'
🌀 Executing on remote database [DATABASE_NAME] (DATABASE_ID):
🌀 To execute on your local development database, remove the --remote flag from your wrangler command.
🚣 Executed 1 commands in 0.5874ms
┌────────┬──────────────────────┬───────┬──────┬────┬────────┐
│ schema │ name │ type │ ncol │ wr │ strict │
├────────┼──────────────────────┼───────┼──────┼────┼────────┤
│ main │ Territory │ table │ 3 │ 0 │ 0 │
├────────┼──────────────────────┼───────┼──────┼────┼────────┤
│ main │ CustomerDemographic │ table │ 2 │ 0 │ 0 │
├────────┼──────────────────────┼───────┼──────┼────┼────────┤
│ main │ OrderDetail │ table │ 6 │ 0 │ 0 │
├────────┼──────────────────────┼───────┼──────┼────┼────────┤
│ main │ sqlite_schema │ table │ 5 │ 0 │ 0 │
├────────┼──────────────────────┼───────┼──────┼────┼────────┤
│ main │ Region │ table │ 2 │ 0 │ 0 │
├────────┼──────────────────────┼───────┼──────┼────┼────────┤
│ main │ _cf_KV │ table │ 2 │ 1 │ 0 │
├────────┼──────────────────────┼───────┼──────┼────┼────────┤
│ main │ ProductDetails_V │ view │ 14 │ 0 │ 0 │
├────────┼──────────────────────┼───────┼──────┼────┼────────┤
│ main │ EmployeeTerritory │ table │ 3 │ 0 │ 0 │
├────────┼──────────────────────┼───────┼──────┼────┼────────┤
│ main │ Employee │ table │ 18 │ 0 │ 0 │
├────────┼──────────────────────┼───────┼──────┼────┼────────┤
│ main │ Category │ table │ 3 │ 0 │ 0 │
├────────┼──────────────────────┼───────┼──────┼────┼────────┤
│ main │ Customer │ table │ 11 │ 0 │ 0 │
├────────┼──────────────────────┼───────┼──────┼────┼────────┤
│ main │ Shipper │ table │ 3 │ 0 │ 0 │
├────────┼──────────────────────┼───────┼──────┼────┼────────┤
│ main │ Supplier │ table │ 12 │ 0 │ 0 │
├────────┼──────────────────────┼───────┼──────┼────┼────────┤
│ main │ Order │ table │ 14 │ 0 │ 0 │
├────────┼──────────────────────┼───────┼──────┼────┼────────┤
│ main │ CustomerCustomerDemo │ table │ 2 │ 0 │ 0 │
├────────┼──────────────────────┼───────┼──────┼────┼────────┤
│ main │ Product │ table │ 10 │ 0 │ 0 │
├────────┼──────────────────────┼───────┼──────┼────┼────────┤
│ temp │ sqlite_temp_schema │ table │ 5 │ 0 │ 0 │
└────────┴──────────────────────┴───────┴──────┴────┴────────┘
PRAGMA table_info("TABLE_NAME")
주어진 TABLE_NAME에 대한 스키마(컬럼, 유형, null, 기본값)를 보여줘요.
반환 값 (Return values)
지정된 테이블의 각 컬럼마다 한 행씩 반환돼요. 각 행에는 다음이 포함돼요.
cid: 행 식별자name: 컬럼의 이름type: 데이터 유형(제공된 경우), 아니면''notnull: 컬럼이 NULL일 수 있으면1, 아니면0dflt_value: 컬럼의 기본값pk: 컬럼이 기본 키이면1, 아니면0
PRAGMA table_info 예시
npx wrangler d1 execute [DATABASE_NAME] --command='PRAGMA table_info("Order")'
🌀 Executing on remote database [DATABASE_NAME] (DATABASE_ID):
🌀 To execute on your local development database, remove the --remote flag from your wrangler command.
🚣 Executed 1 commands in 0.8502ms
┌─────┬────────────────┬───────────────┬─────────┬────────────┬────┐
│ cid │ name │ type │ notnull │ dflt_value │ pk │
├─────┼────────────────┼───────────────┼─────────┼────────────┼────┤
│ 0 │ Id │ INTEGER │ 0 │ │ 1 │
├─────┼────────────────┼───────────────┼─────────┼────────────┼────┤
│ 1 │ CustomerId │ VARCHAR(8000) │ 0 │ │ 0 │
├─────┼────────────────┼───────────────┼─────────┼────────────┼────┤
│ 2 │ EmployeeId │ INTEGER │ 1 │ │ 0 │
├─────┼────────────────┼───────────────┼─────────┼────────────┼────┤
│ 3 │ OrderDate │ VARCHAR(8000) │ 0 │ │ 0 │
├─────┼────────────────┼───────────────┼─────────┼────────────┼────┤
│ 4 │ RequiredDate │ VARCHAR(8000) │ 0 │ │ 0 │
├─────┼────────────────┼───────────────┼─────────┼────────────┼────┤
│ 5 │ ShippedDate │ VARCHAR(8000) │ 0 │ │ 0 │
├─────┼────────────────┼───────────────┼─────────┼────────────┼────┤
│ 6 │ ShipVia │ INTEGER │ 0 │ │ 0 │
├─────┼────────────────┼───────────────┼─────────┼────────────┼────┤
│ 7 │ Freight │ DECIMAL │ 1 │ │ 0 │
├─────┼────────────────┼───────────────┼─────────┼────────────┼────┤
│ 8 │ ShipName │ VARCHAR(8000) │ 0 │ │ 0 │
├─────┼────────────────┼───────────────┼─────────┼────────────┼────┤
│ 9 │ ShipAddress │ VARCHAR(8000) │ 0 │ │ 0 │
├─────┼────────────────┼───────────────┼─────────┼────────────┼────┤
│ 10 │ ShipCity │ VARCHAR(8000) │ 0 │ │ 0 │
├─────┼────────────────┼───────────────┼─────────┼────────────┼────┤
│ 11 │ ShipRegion │ VARCHAR(8000) │ 0 │ │ 0 │
├─────┼────────────────┼───────────────┼─────────┼────────────┼────┤
│ 12 │ ShipPostalCode │ VARCHAR(8000) │ 0 │ │ 0 │
├─────┼────────────────┼───────────────┼─────────┼────────────┼────┤
│ 13 │ ShipCountry │ VARCHAR(8000) │ 0 │ │ 0 │
└─────┴────────────────┴───────────────┴─────────┴────────────┴────┘
PRAGMA table_xinfo("TABLE_NAME")
PRAGMA table_info(TABLE_NAME)와 비슷하지만 생성된 컬럼도 포함해요.
PRAGMA table_xinfo 예시
npx wrangler d1 execute [DATABASE_NAME] --command='PRAGMA table_xinfo("Order")'
🌀 Executing on remote database [DATABASE_NAME] (DATABASE_ID):
🌀 To execute on your local development database, remove the --remote flag from your wrangler command.
🚣 Executed 1 commands in 0.3854ms
┌─────┬────────────────┬───────────────┬─────────┬────────────┬────┬────────┐
│ cid │ name │ type │ notnull │ dflt_value │ pk │ hidden │
├─────┼────────────────┼───────────────┼─────────┼────────────┼────┼────────┤
│ 0 │ Id │ INTEGER │ 0 │ │ 1 │ 0 │
├─────┼────────────────┼───────────────┼─────────┼────────────┼────┼────────┤
│ 1 │ CustomerId │ VARCHAR(8000) │ 0 │ │ 0 │ 0 │
├─────┼────────────────┼───────────────┼─────────┼────────────┼────┼────────┤
│ 2 │ EmployeeId │ INTEGER │ 1 │ │ 0 │ 0 │
├─────┼────────────────┼───────────────┼─────────┼────────────┼────┼────────┤
│ 3 │ OrderDate │ VARCHAR(8000) │ 0 │ │ 0 │ 0 │
├─────┼────────────────┼───────────────┼─────────┼────────────┼────┼────────┤
│ 4 │ RequiredDate │ VARCHAR(8000) │ 0 │ │ 0 │ 0 │
├─────┼────────────────┼───────────────┼─────────┼────────────┼────┼────────┤
│ 5 │ ShippedDate │ VARCHAR(8000) │ 0 │ │ 0 │ 0 │
├─────┼────────────────┼───────────────┼─────────┼────────────┼────┼────────┤
│ 6 │ ShipVia │ INTEGER │ 0 │ │ 0 │ 0 │
├─────┼────────────────┼───────────────┼─────────┼────────────┼────┼────────┤
│ 7 │ Freight │ DECIMAL │ 1 │ │ 0 │ 0 │
├─────┼────────────────┼───────────────┼─────────┼────────────┼────┼────────┤
│ 8 │ ShipName │ VARCHAR(8000) │ 0 │ │ 0 │ 0 │
├─────┼────────────────┼───────────────┼─────────┼────────────┼────┼────────┤
│ 9 │ ShipAddress │ VARCHAR(8000) │ 0 │ │ 0 │ 0 │
├─────┼────────────────┼───────────────┼─────────┼────────────┼────┼────────┤
│ 10 │ ShipCity │ VARCHAR(8000) │ 0 │ │ 0 │ 0 │
├─────┼────────────────┼───────────────┼─────────┼────────────┼────┼────────┤
│ 11 │ ShipRegion │ VARCHAR(8000) │ 0 │ │ 0 │ 0 │
├─────┼────────────────┼───────────────┼─────────┼────────────┼────┼────────┤
│ 12 │ ShipPostalCode │ VARCHAR(8000) │ 0 │ │ 0 │ 0 │
├─────┼────────────────┼───────────────┼─────────┼────────────┼────┼────────┤
│ 13 │ ShipCountry │ VARCHAR(8000) │ 0 │ │ 0 │ 0 │
└─────┴────────────────┴───────────────┴─────────┴────────────┴────┴────────┘
PRAGMA index_list("TABLE_NAME")
주어진 TABLE_NAME에 대한 인덱스를 보여줘요.
반환 값 (Return values)
지정된 테이블과 연결된 각 인덱스마다 한 행씩 반환돼요. 각 행에는 다음이 포함돼요.
seq: 내부 추적용 시퀀스 번호name: 인덱스의 이름unique: 인덱스가 UNIQUE면1, 아니면0origin: 인덱스의 기원(CREATE INDEX문으로 생성되면c, UNIQUE 제약 조건으로 생성되면u, PRIMARY KEY 제약 조건으로 생성되면pk)partial: 부분 인덱스(partial index)면1, 아니면0
PRAGMA index_list 예시
npx wrangler d1 execute [DATABASE_NAME] --command='PRAGMA index_list("Territory")'
🌀 Executing on remote database d1-pragma-db (DATABASE_ID):
🌀 To execute on your local development database, remove the --remote flag from your wrangler command.
🚣 Executed 1 commands in 0.2177ms
┌─────┬──────────────────────────────┬────────┬────────┬─────────┐
│ seq │ name │ unique │ origin │ partial │
├─────┼──────────────────────────────┼────────┼────────┼─────────┤
│ 0 │ sqlite_autoindex_Territory_1 │ 1 │ pk │ 0 │
└─────┴──────────────────────────────┴────────┴────────┴─────────┘
PRAGMA index_info(INDEX_NAME)
주어진 INDEX_NAME에 대한 인덱스된 컬럼(들)을 보여줘요.
반환 값 (Return values)
지정된 인덱스의 각 키 컬럼마다 한 행씩 반환돼요. 각 행에는 다음이 포함돼요.
seqno: 인덱스 내 컬럼의 순위cid: 인덱스되고 있는 테이블 내 컬럼의 순위name: 인덱스되고 있는 컬럼의 이름
PRAGMA index_info 예시
npx wrangler d1 execute [DATABASE_NAME] --command='PRAGMA index_info("sqlite_autoindex_Territory_1")'
🌀 Executing on remote database d1-pragma-db (DATABASE_ID):
🌀 To execute on your local development database, remove the --remote flag from your wrangler command.
🚣 Executed 1 commands in 0.2523ms
┌───────┬─────┬──────┐
│ seqno │ cid │ name │
├───────┼─────┼──────┤
│ 0 │ 0 │ Id │
└───────┴─────┴──────┘
PRAGMA index_xinfo("INDEX_NAME")
PRAGMA index_info("TABLE_NAME")와 비슷하지만 숨겨진 컬럼도 포함해요.
PRAGMA index_xinfo 예시
npx wrangler d1 execute [DATABASE_NAME] --command='PRAGMA index_xinfo("sqlite_autoindex_Territory_1")'
🌀 Executing on remote database d1-pragma-db (DATABASE_ID):
🌀 To execute on your local development database, remove the --remote flag from your wrangler command.
🚣 Executed 1 commands in 0.6034ms
┌───────┬─────┬──────┬──────┬────────┬─────┐
│ seqno │ cid │ name │ desc │ coll │ key │
├───────┼─────┼──────┼──────┼────────┼─────┤
│ 0 │ 0 │ Id │ 0 │ BINARY │ 1 │
├───────┼─────┼──────┼──────┼────────┼─────┤
│ 1 │ -1 │ │ 0 │ BINARY │ 0 │
└───────┴─────┴──────┴──────┴────────┴─────┘
PRAGMA quick_check
테이블의 형식과 일관성을 검사하며, 다음 사항을 포함해요.
- 잘못된 형식의 레코드
- 누락된 페이지
- 여러 번 사용되거나 전혀 사용되지 않는 데이터베이스의 섹션
반환 값 (Return values)
- 오류가 없으면:
OK값이 있는 단일 행 - 오류가 있으면: 검사가 지적한 문제를 설명하는 문자열
PRAGMA quick_check 예시
npx wrangler d1 execute [DATABASE_NAME] --command='PRAGMA quick_check'
🌀 Executing on remote database [DATABASE_NAME] (DATABASE_ID):
🌀 To execute on your local development database, remove the --remote flag from your wrangler command.
🚣 Executed 1 commands in 1.4073ms
┌─────────────┐
│ quick_check │
├─────────────┤
│ ok │
└─────────────┘
PRAGMA foreign_key_check
선택한 테이블에서 외래 키의 잘못된 참조가 있는지 검사해요.
PRAGMA foreign_key_list("TABLE_NAME")
선택한 테이블의 외래 키 제약 조건을 나열해요.
PRAGMA case_sensitive_like = (on|off)
LIKE 연산자의 대소문자 구분을 전환해요. PRAGMA case_sensitive_like가 설정된 경우:
ON: 'a' LIKE 'A'는 false예요.OFF: 'a' LIKE 'A'는 true예요. (LIKE 연산자의 기본 동작이에요.)
PRAGMA ignore_check_constraints = (on|off)
CHECK 제약 조건의 적용을 전환해요. PRAGMA ignore_check_constraints가 설정된 경우:
ON: CHECK 제약 조건이 무시돼요.OFF: CHECK 제약 조건이 적용돼요. (기본 동작이에요.)
PRAGMA legacy_alter_table = (on|off)
SQLite의 이전 버전(3.24.0) 이전/이후의 ALTER TABLE RENAME 명령 동작을 전환해요. PRAGMA legacy_alter_table이 설정된 경우:
ON: ALTER TABLE RENAME은 CREATE TABLE 문과 관련 CREATE INDEX·CREATE TRIGGER 문에서 테이블 이름의 첫 번째 출현만 다시 작성해요. 그 외의 모든 출현은 수정되지 않아요.OFF: ALTER TABLE RENAME은 스키마에서 테이블 이름에 대한 모든 참조를 다시 작성해요. (기본 동작이에요.)
PRAGMA recursive_triggers = (on|off)
재귀 트리거 기능을 전환해요. PRAGMA recursive_triggers가 설정된 경우:
ON: 발화된 트리거가 다른 트리거를 활성화할 수 있어요. (단일 트리거가 같은 행에 여러 번 발화될 수 있어요.)OFF: 발화된 트리거가 다른 트리거를 활성화할 수 없어요.
PRAGMA reverse_unordered_selects = (on|off)
ORDER BY 절이 없는 SELECT 문 결과의 순서를 전환해요. PRAGMA reverse_unordered_selects가 설정된 경우:
ON: SELECT 문 결과의 순서를 반대로 해요.OFF: SELECT 문 결과를 일반적인 순서로 반환해요.
PRAGMA foreign_keys = (on|off)
외래 키 제약 조건 적용을 전환해요. PRAGMA foreign_keys가 설정된 경우:
ON: 외래 키 제약 조건을 위반하는 작업을 중지해요.OFF: 외래 키 제약 조건을 위반하는 작업을 허용해요.
PRAGMA defer_foreign_keys = (on|off)
외래 키 제약 조건의 적용을 현재 트랜잭션이 끝날 때까지 지연시킬 수 있게 해줘요. 스키마 변경이 적용되는 순서에 따라 제약 조건을 일시적으로 위반할 수 있으므로 데이터베이스 마이그레이션 중에 유용할 수 있어요.
이것은 현재 트랜잭션 밖의 외래 키 강제를 비활성화하지는 않아요. 트랜잭션이 끝날 때 해결되지 않은 외래 키 위반이 있다면 FOREIGN KEY constraint failed 오류와 함께 실패해요.
PRAGMA defer_foreign_keys = ON을 설정해도 ON DELETE CASCADE 액션이 실행되는 것을 막지는 않는다는 점에 유의하세요. 외래 키 제약 조건 검사가 트랜잭션 끝까지 지연되는 동안에도 ON DELETE CASCADE 작업은 SQLite의 동작과 일관되게 활성 상태로 유지돼요.
외래 키 강제를 지연시키려면 트랜잭션 시작 시 또는 제약 조건을 위반할 변경 앞에 PRAGMA defer_foreign_keys = on을 설정하세요.
-- Defer foreign key enforcement in this transaction.
PRAGMA defer_foreign_keys = on
-- Run your CREATE TABLE or ALTER TABLE / COLUMN statements
ALTER TABLE users ...
-- This is implicit if not set by the end of the transaction.
PRAGMA defer_foreign_keys = off
외래 키 다루는 방법에 대한 자세한 내용은 외래 키 문서를 참조하세요.
PRAGMA optimize
필요하다면 각 테이블에 대해 ANALYZE 명령을 실행해 데이터베이스의 모든 스키마를 최적화하려고 시도해요. ANALYZE는 테이블과 인덱스에 대한 통계를 담고 있는 내부 테이블을 업데이트해요. 이 통계는 쿼리 플래너가 입력 쿼리를 더 효율적으로 실행하는 데 도움을 줘요.
PRAGMA optimize가 ANALYZE를 실행할 때 명령이 너무 오래 걸리지 않도록 제한을 설정해요. 또는 PRAGMA optimize가 ANALYZE 실행이 불필요하다고 판단할 수도 있어요(예: 스키마가 크게 변경되지 않은 경우). 이 경우에는 최적화가 수행되지 않아요.
스키마를 변경한 후(예: 인덱스를 생성한 후) 이 명령을 실행하는 것을 권장해요.
PRAGMA optimize가 데이터베이스를 최적화하는 방법에 대한 자세한 내용은 SQLite PRAGMA optimize 문서 ↗︎를 참조하세요.
sqlite_master 쿼리하기
sqlite_master 테이블을 쿼리해 모든 테이블, 인덱스, 그리고 그것들을 생성하는 데 사용된 원본 SQL을 보여줄 수도 있어요.
SELECT name, sql FROM sqlite_master
{
"name": "users",
"sql": "CREATE TABLE users ( user_id INTEGER PRIMARY KEY, email_address TEXT, created_at INTEGER, deleted INTEGER, settings TEXT)"
},
{
"name": "idx_ordered_users",
"sql": "CREATE INDEX idx_ordered_users ON users(created_at DESC)"
},
{
"name": "Order",
"sql": "CREATE TABLE \"Order\" ( \"Id\" INTEGER PRIMARY KEY, \"CustomerId\" VARCHAR(8000) NULL, \"EmployeeId\" INTEGER NOT NULL, \"OrderDate\" VARCHAR(8000) NULL, \"RequiredDate\" VARCHAR(8000) NULL, \"ShippedDate\" VARCHAR(8000) NULL, \"ShipVia\" INTEGER NULL, \"Freight\" DECIMAL NOT NULL, \"ShipName\" VARCHAR(8000) NULL, \"ShipAddress\" VARCHAR(8000) NULL, \"ShipCity\" VARCHAR(8000) NULL, \"ShipRegion\" VARCHAR(8000) NULL, \"ShipPostalCode\" VARCHAR(8000) NULL, \"ShipCountry\" VARCHAR(8000) NULL)"
},
{
"name": "Product",
"sql": "CREATE TABLE \"Product\" ( \"Id\" INTEGER PRIMARY KEY, \"ProductName\" VARCHAR(8000) NULL, \"SupplierId\" INTEGER NOT NULL, \"CategoryId\" INTEGER NOT NULL, \"QuantityPerUnit\" VARCHAR(8000) NULL, \"UnitPrice\" DECIMAL NOT NULL, \"UnitsInStock\" INTEGER NOT NULL, \"UnitsOnOrder\" INTEGER NOT NULL, \"ReorderLevel\" INTEGER NOT NULL, \"Discontinued\" INTEGER NOT NULL)"
}
LIKE로 검색하기 (Search with LIKE)
SQL의 LIKE 연산자를 사용해 검색을 수행할 수 있어요.
const { results } = await env.DB.prepare(
"SELECT * FROM Customers WHERE CompanyName LIKE ?",
)
.bind("%eve%")
.run();
console.log("results: ", results);
results: [...]
관련 리소스 (Related resources)
- D1에서 인덱스를 만드는 방법을 배워보세요.
- D1의 JSON 함수를 사용해 JSON 데이터를 쿼리하세요.
wrangler dev를 사용해 Worker와 D1을 로컬에서 실행하고 배포 전에 문제를 디버깅하세요.