DML
INSERT
Section titled “INSERT”INSERT INTO orders (customer_name, amount)VALUES ('Alice Smith', 149.99);RETURNING
Section titled “RETURNING”Return values from the inserted row:
INSERT INTO orders (customer_name, amount)VALUES ('Bob Johnson', 75.50)RETURNING id;
INSERT INTO orders (customer_name, amount)VALUES ('Carol', 200.00)RETURNING *;Insert from a Query
Section titled “Insert from a Query”INSERT INTO archive (customer_name, amount)SELECT customer_name, amount FROM orders WHERE status = 'delivered';INSERT … ON CONFLICT (Upsert)
Section titled “INSERT … ON CONFLICT (Upsert)”Skip conflicting rows:
INSERT INTO users (email, name)VALUES ('alice@example.com', 'Alice')ON CONFLICT DO NOTHING;Update on conflict with specific columns:
INSERT INTO users (email, name)VALUES ('alice@example.com', 'Alice Updated')ON CONFLICT (email) DO UPDATE SET name = 'Alice Updated';Can be combined with RETURNING:
INSERT INTO users (email, name)VALUES ('alice@example.com', 'Alice')ON CONFLICT (email) DO UPDATE SET name = 'Alice'RETURNING *;UPDATE
Section titled “UPDATE”UPDATE orders SET status = 'shipped' WHERE amount > 100;Bulk Update from VALUES
Section titled “Bulk Update from VALUES”PostgreSQL-style UPDATE ... FROM:
UPDATE orders SET status = d.status FROM (VALUES ('ord-1', 'shipped'), ('ord-2', 'delivered')) AS d (id, status) WHERE orders.id = d.id;UPDATE with RETURNING
Section titled “UPDATE with RETURNING”UPDATE orders SET status = 'shipped'WHERE id = 42RETURNING id, status;DELETE
Section titled “DELETE”DELETE FROM orders WHERE status = 'delivered';DELETE … USING
Section titled “DELETE … USING”Join other tables to determine which rows to delete:
DELETE FROM ordersUSING customersWHERE orders.customer_id = customers.id AND customers.status = 'inactive';Multiple USING tables:
DELETE FROM order_itemsUSING products, categoriesWHERE order_items.product_id = products.id AND products.category_id = categories.id AND categories.name = 'discontinued';DELETE with RETURNING
Section titled “DELETE with RETURNING”DELETE FROM orders WHERE status = 'delivered'RETURNING *;Bulk import and export data in CSV format.
COPY FROM
Section titled “COPY FROM”Import rows from a CSV file:
COPY orders FROM 'data/orders.csv';COPY orders FROM 'data/orders.csv' WITH (HEADER);COPY orders FROM 'data/orders.csv' WITH (HEADER, DELIMITER '|');COPY orders (customer_name, amount) FROM 'data/partial.csv' WITH (HEADER);COPY TO
Section titled “COPY TO”Export a table or query to a CSV file:
COPY orders TO 'export/orders.csv';COPY orders TO 'export/orders.csv' WITH (HEADER);COPY (SELECT * FROM orders WHERE status = 'pending') TO 'export/pending.csv' WITH (HEADER);Options
Section titled “Options”| Option | Description |
|---|---|
HEADER | First row is a header (skipped on import, written on export) |
DELIMITER 'c' | Field separator character (default: ,) |
csv_file() — Query CSV Files Directly
Section titled “csv_file() — Query CSV Files Directly”Query a CSV file as a virtual table without importing:
SELECT * FROM csv_file('data/sales.csv');SELECT name, age::int FROM csv_file('data/people.csv') WHERE age::int > 25;All values are returned as TEXT — use ::type to cast. Supports WHERE, ORDER BY, LIMIT, JOIN, and aggregates.
Options:
csv_file('path') -- with header (default)csv_file('path', false) -- no header (columns named column1, column2, ...)csv_file('path', true, '|') -- custom delimiterJoin CSV files with each other or with database tables:
SELECT e.name, d.departmentFROM csv_file('employees.csv') eJOIN csv_file('departments.csv') d ON e.dept_id = d.id;Virtual Tables
Section titled “Virtual Tables”Register external data sources as queryable tables using CREATE VIRTUAL TABLE:
CREATE VIRTUAL TABLE sales USING csv('data/sales.csv');CREATE VIRTUAL TABLE sales USING csv('data/sales.csv', 'no_header', '|');
SELECT * FROM sales WHERE amount::int > 100;DROP TABLE sales;Virtual tables appear in SHOW TABLES and support SELECT, WHERE, JOIN, ORDER BY, and aggregates. They are read-only — INSERT, UPDATE, and DELETE are not supported.
The built-in csv module is registered by default. Custom modules can be registered via the Scala API:
db.registerVirtualTableModule("mymodule", new VirtualTableModule { ... })