Skip to content
masterclassBuddyTech Buzz5 fresh blogs · 5:00 AM IST

Prisma · Module

$queryRawUnsafe

$queryRawUnsafe executes raw SQL and returns query records. Use it only with trusted SQL structure or correctly parameterized values, because user-controlled interpolation can enable SQL injection.

How it works

$queryRawUnsafe sends a raw SQL string or template string to the database and returns the records produced by the query. It is useful when SQL structure, such as a table name, must be dynamic, but interpolating untrusted input can enable SQL injection, so $queryRaw is preferred whenever possible.

Syntax

prisma.$queryRawUnsafe(query: string, ...values: unknown[]): PrismaPromise<T>

Parameters

NameTypeDescription
querystring or template stringRaw SQL text or a template string to execute; parameter values may be supplied using the database provider's placeholder syntax.
valuesprovider-specific parameter valuesValues corresponding to SQL placeholders, such as ? for MySQL or $1, $2, and later positions for PostgreSQL.

Returns

A promise resolving to the records returned by the SQL query.

Key points

  • Pass SQL as a regular string or template string rather than relying on Prisma’s tagged-template safety behavior.
  • Use it for queries that return rows, especially SQL statements such as SELECT.
  • A table identifier cannot be inserted into $queryRaw; this is a case where the unsafe method may be required.
  • For dynamic table names, construct the query only from trusted or allow-listed identifiers.
  • The method supports binding values through ordinary provider-specific parameterized SQL.
  • Unsafe construction can do more than reveal data: injected SQL may alter or delete it.

Common mistakes

  • Do not interpolate user-controlled values into the SQL string; malicious input can modify or delete data.
  • Prefer the tagged-template $queryRaw API when it can express the query safely.
  • If using parameters with this API, use the placeholder syntax required by the database provider.

Example: Query a dynamic table

import { PrismaClient } from "@prisma/client";

const prisma = new PrismaClient();

async function main() {
  const table = "User";
  const users = await prisma.$queryRawUnsafe<Array<{ id: number }>>(
    `SELECT id FROM ${table}`
  );
  console.log(users);
}

main().finally(() => prisma.$disconnect());

Reads records from a dynamically selected table; the table name must come from a trusted source.

When to use it

Dynamic table identifiers

The SQL query must select from a table whose name is chosen from a trusted, allow-listed set.

Database-specific raw SQL

A provider-specific SQL feature or optimized statement is needed and Prisma’s query API cannot express it.

Raw record retrieval

A read query must return rows rather than merely report affected-row counts.

Interview questions

QWhat does $queryRawUnsafe do, and when is it useful?

It executes a raw SQL string or template string and returns records, such as rows from a SELECT query. Unlike the safer tagged-template API, its SQL text can contain dynamically constructed structure.

Follow-up: How would you avoid injection when a value is dynamic? Use database-specific placeholders and pass values separately, or use $queryRaw with interpolation for supported value expressions.

QWhy might an application choose $queryRawUnsafe over $queryRaw?

It is useful when SQL identifiers such as table names must be dynamic, because $queryRaw cannot interpolate table names. The dynamic identifier must nevertheless be trusted or safely allow-listed.

Follow-up: Why can’t a normal value placeholder solve this? Database placeholders represent values, not SQL identifiers, so a table name cannot generally be bound as a parameter.

QHow can $queryRawUnsafe still be used more safely?

It supports standard parameterized queries using provider-specific placeholders: ? for MySQL and $1, $2, and later positions for PostgreSQL. Parameterization is safer than concatenating untrusted values into SQL.

Follow-up: What is the preferred alternative when the query does not require a dynamic identifier? Use $queryRaw with a tagged template, because the documentation describes it as significantly safer when used correctly.

  • $queryRaw
  • $executeRaw
  • $executeRawUnsafe
  • raw queries
  • parameterized queries

Source: Raw queries - Prisma Documentation. Checked 2026-10-16.