Validated dynamic table selection
A query must select from one of several predetermined tables.
Neon · Module
sql.unsafe() embeds a trusted raw SQL string in a Neon tagged-template query. Use it for validated identifiers such as table or column names, never for untrusted input.
sql.unsafe() inserts a trusted raw SQL string into a tagged-template query instead of treating it as a parameter value. This is intended for SQL fragments such as validated table or column names that cannot be passed as ordinary interpolated values; untrusted input must not reach it.
sql.unsafe(value)| Name | Type | Description |
|---|---|---|
value | string | A trusted SQL string or identifier to embed directly in the tagged-template query. |
The documentation page does not specify a separate return type for sql.unsafe(); it is used inside a Neon tagged-template query.
import { neon } from '@neondatabase/serverless';
const sql = neon(process.env.DATABASE_URL!);
const tableName = 'posts';
const rows = await sql`SELECT * FROM ${sql.unsafe(tableName)} WHERE id = ${1}`;
console.log(rows);Use unsafe() only after restricting the interpolated identifier to trusted, predetermined values.
A query must select from one of several predetermined tables.
A trusted application configuration determines a column or table identifier.
unsafe() allows a trusted raw SQL string to be embedded in a tagged-template query. It is useful for identifiers such as table names, which cannot be supplied as ordinary parameter values.
Follow-up: How should a dynamic table name be handled? Validate it against a fixed allowlist, then pass only the validated value to unsafe(); reject every other value.
Ordinary interpolation in the Neon tagged template is parameterized and is designed to protect against SQL injection. unsafe() deliberately bypasses that treatment for trusted SQL text.
Follow-up: What should happen with an untrusted value? Keep it as a normal interpolation so the driver sends it as a parameter rather than SQL syntax.
The documented form is a tagged template such as sqlSELECT * FROM ${sql.unsafe(tableName)} WHERE id = ${id}. The query function returned by neon() is not used as a conventional function call in the stable interface.
Follow-up: What is the alternative for manually numbered placeholders? Use sql.query(queryText, values).
neonsql.querytagged-template queries