Skip to content

db.query()

db.query() is the primary method for executing SQL statements.

It supports several invocation forms.


Signatures

ts
db.query(sql: string): Promise<Result>
db.query(sql: string, options: QueryOptions): Promise<Result>
db.query(sql: string, values: any[]): Promise<Result>
db.query(sql: string, callback: Function, options: QueryOptions): Promise<RealtimeResult>
db.query(queryLike: { query: string; ... }): Promise<Result>
db.query(queryLike: { text: string; ... }): Promise<Result>

General Behavior

db.query():

  • executes the provided SQL text
  • accepts parameters either positionally or through options.values
  • accepts runtime options such as dialect, live, signal, id, or tx
  • returns either a Result or, for live queries, a RealtimeResult

Two Execution Modes

db.query() operates in two distinct modes:

  1. one-shot mode returning a Result
  2. live mode with { live: true } returning a RealtimeResult

Here, { live: true } is not just a flag. It changes the lifecycle of the query:

ModeLifecycleResult type
one-shotexecutes and completesResult
livestays active and updates over timeRealtimeResult

Examples

Basic Query Execution

js
const result = await db.query('SELECT * FROM users');

This executes the query and buffers the full result set into result.rows.

Parameterized Query

Parameters as a second argument:

js
const result = await db.query('SELECT * FROM users WHERE active = $1', [true]);

Query With Options

Parameters through options.values:

js
const result = await db.query('SELECT * FROM users WHERE created_at >= $1', {
  values: [new Date('2026-01-01')],
});

Live query form:

js
const result = await db.query('SELECT id, title FROM posts ORDER BY id', { live: true });

In live mode, the query stays open and result.rows becomes a live result set.

Query With a Callback

A live query can pass a callback for direct commit-events handling:

js
const commits = [];

const result = await db.query(
  'SELECT id, title FROM posts ORDER BY id',
  (commit) => commits.push(commit),
  { live: true }
);

The callback form changes the delivery model:

  • result.rows carries the initial result set and remains static
  • subsequent updates are emitted to the callback as commit events

Result

Result represents the outcome of a regular query.

All non-live query() operations return a Result object that can contain both row data and write metadata, though only one of those is meaningful for a given statement.

Properties

PropertyTypeDescription
rowsany[]result set as an array of row objects
rowCountnumbernumber of rows affected by a non-returning write
affectedRowsnumberalias of rowCount, useful for MySQL/MariaDB-style code

Reading Result Correctly

rowCount is not the number of returned rows.

It is instead the number of rows affected by an INSERT, UPDATE, or DELETE that does not itself return rows.

Quick reference:

OperationReturns rowsAffects rowCount
SELECTyesno
INSERT/UPDATE/DELETE ... RETURNINGyesno
INSERT/UPDATE/DELETEnoyes

Examples

A Fetch Operation

js
const result = await db.query('SELECT id, name FROM users');
console.log(result.rows);
// [{ id: 1, name: 'Ada' }]
console.log(result.rowCount);
// 0 – not applicable to the query

A Write Operation With RETURNING

js
const result = await db.query(
  'INSERT INTO users (name) VALUES ($1) RETURNING *',
  ['Bob']
);
console.log(result.rows);
// [{ id: 2, name: 'Bob' }]
console.log(result.rowCount);
// 0 – not applicable to the query

A Write Operation Without RETURNING

js
const result = await db.query(
  'INSERT INTO users (name) VALUES ($1)',
  ['Eve']
);
console.log(result.rowCount);
// 1
console.log(result.rows);
// [] – not applicable to the query

RealtimeResult

RealtimeResult is the result of a live query: a query executed with { live: true }.

It extends the ordinary idea of a Result into a live, self-updating result.

Properties

PropertyTypeDescription
rowsany[]result rows; in non-callback live mode this is the self-updating live view, while in callback mode it carries the initial result set
hashesstring[]internal row identifiers used for diff tracking
modestringdelivery mode: 'live' or 'callback'
initialbooleanindicates whether this query produced a fresh initial result or resumed from an existing subscription slot

IMPORTANT

Treat rows and hashes as read-only. Manual mutation can desynchronize the internal state that keeps the live result coherent.

Methods

await result.abort()

Terminates the live query and stops further updates to the live view.

js
await result.abort();

If the live query was created with a stable id, pass { forget: true } to also drop the internal slot bound to that id:

js
await result.abort({ forget: true });

Example

js
const result = await db.query(
  'SELECT id, name FROM users ORDER BY id',
  { live: true }
);

console.log(result.rows);
console.log(result.mode);

await result.abort();

Additional Reading

If you want to learn about...Go to...
the related stream() APIQuery API
live queries in detailLive Queries
querying within a transactionTransaction API

MIT Licensed