NitroSQLite
Guides

Parameters and results

Bind SQLite values, inspect rows and metadata, and handle query failures.

SQLite parameters let you write SQL with placeholders and supply its values separately. SQLite binds each value to a placeholder when it runs the statement, which is useful for searches and writes that depend on user or app data. A query result contains the rows returned by a read, or information about the rows changed by a write.

In NitroSQLite, pass positional values in an array for ? placeholders. The public SQLiteValue type permits boolean, number, string, ArrayBuffer, and null. Keep table and column names in your own SQL; parameters bind values, not identifiers.

const name = 'Ada'
const age = 37

db.execute('INSERT INTO people (name, age) VALUES (?, ?)', [name, age])

const result = await db.executeAsync<{ name: string; age: number }>(
  'SELECT name, age FROM people WHERE age >= ?',
  [18],
)

for (const person of result.rows._array) {
  console.log(person.name, person.age)
}

results is an array of row objects keyed by column name. Its values retain the general SQLiteValue type. The connection adds rows._array with the same rows, rows.length, and rows.item(index). The row generic applies to rows._array and rows.item(); it does not validate values at runtime. item() returns undefined outside the array bounds. For a SELECT, use rows.length or results.length to count returned rows. rowsAffected uses SQLite's last change count, which can retain an earlier write's count after a SELECT; use it for INSERT, UPDATE, or DELETE. insertId exposes SQLite's last insert row ID when available and can also refer to an earlier statement.

SQLite INTEGER and REAL result values both arrive as JavaScript numbers. BLOB values arrive as ArrayBuffer; NULL values arrive as null. A bound boolean is stored through SQLite's integer binding, so read it as a number and convert it in application code if needed. JavaScript numbers cannot represent every 64-bit SQLite integer exactly; choose a storage representation appropriate for identifiers that exceed the safe integer range.

Column metadata

For a query with result columns, metadata maps column names to { name, type, index }. In the current native implementation, metadata.type is unreliable for detecting a column's declared SQL type. Use your schema for that decision. An expression without a declared type maps to NULL_VALUE, which does not mean the result itself is null. See query result types and errors for the metadata shape and the current mapping limitation.

const result = db.execute('SELECT name FROM people LIMIT 1')
const nameColumn = result.metadata?.name

if (nameColumn) {
  console.log(nameColumn.name, nameColumn.index)
}

Be especially careful with nullable columns and expressions when specifying a row type.

Errors

The connection's JavaScript helpers normalize database failures to NitroSQLiteError. Async methods reject; sync methods throw. Catch the error around the operation you can recover from:

import { NitroSQLiteError } from 'react-native-nitro-sqlite'

try {
  await db.executeAsync('SELECT * FROM missing_table')
} catch (error) {
  if (error instanceof NitroSQLiteError) {
    console.error(error.message)
  } else {
    throw error
  }
}

See the query result API for exact types.