skills/prisma-client-api-raw-queries/SKILL.md
Raw Queries. Reference when using this Prisma feature.
npx skillsauth add prisma/cursor-plugin prisma-client-api-raw-queriesInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Execute raw SQL when Prisma's query API isn't sufficient.
Execute SELECT queries and get typed results:
const users = await prisma.$queryRaw`
SELECT * FROM "User" WHERE email LIKE ${'%@prisma.io'}
`
type User = { id: number; email: string; name: string | null }
const users = await prisma.$queryRaw<User[]>`
SELECT id, email, name FROM "User" WHERE role = ${'ADMIN'}
`
Use Prisma.raw() for identifiers (not safe for user input):
import { Prisma } from '../generated/client'
const column = 'email'
const users = await prisma.$queryRaw`
SELECT ${Prisma.raw(column)} FROM "User"
`
Build queries dynamically:
import { Prisma } from '../generated/client'
const email = '[email protected]'
const query = Prisma.sql`SELECT * FROM "User" WHERE email = ${email}`
const users = await prisma.$queryRaw(query)
import { Prisma } from '../generated/client'
const conditions = [
Prisma.sql`role = ${'ADMIN'}`,
Prisma.sql`verified = ${true}`
]
const users = await prisma.$queryRaw`
SELECT * FROM "User"
WHERE ${Prisma.join(conditions, ' AND ')}
`
Execute INSERT, UPDATE, DELETE (returns affected count):
const count = await prisma.$executeRaw`
UPDATE "User" SET verified = true WHERE email LIKE ${'%@prisma.io'}
`
console.log(`Updated ${count} users`)
const deleted = await prisma.$executeRaw`
DELETE FROM "User" WHERE "deletedAt" < ${thirtyDaysAgo}
`
const inserted = await prisma.$executeRaw`
INSERT INTO "Log" (message, level, timestamp)
VALUES (${message}, ${level}, ${new Date()})
`
For fully dynamic queries (use with caution!):
// ⚠️ SQL injection risk - only use with trusted input
const table = 'User'
const users = await prisma.$queryRawUnsafe(
`SELECT * FROM "${table}" WHERE id = $1`,
userId
)
const result = await prisma.$executeRawUnsafe(
'UPDATE "User" SET name = $1 WHERE id = $2',
'Alice',
1
)
// ✅ User input is parameterized
const email = userInput
const users = await prisma.$queryRaw`
SELECT * FROM "User" WHERE email = ${email}
`
// ❌ SQL injection vulnerability!
const email = userInput
const users = await prisma.$queryRawUnsafe(
`SELECT * FROM "User" WHERE email = '${email}'`
)
// Array operations
const users = await prisma.$queryRaw`
SELECT * FROM "User" WHERE 'admin' = ANY(roles)
`
// JSON operations
const users = await prisma.$queryRaw`
SELECT * FROM "User" WHERE metadata->>'theme' = 'dark'
`
// Full-text search
const posts = await prisma.$queryRaw`
SELECT * FROM Post WHERE MATCH(title, content) AGAINST(${searchTerm})
`
await prisma.$transaction(async (tx) => {
await tx.$executeRaw`UPDATE "Account" SET balance = balance - ${amount} WHERE id = ${senderId}`
await tx.$executeRaw`UPDATE "Account" SET balance = balance + ${amount} WHERE id = ${recipientId}`
})
PostgreSQL returns BigInt for COUNT:
const result = await prisma.$queryRaw<[{ count: bigint }]>`
SELECT COUNT(*) as count FROM "User"
`
const count = Number(result[0].count)
type Result = { createdAt: Date }
const users = await prisma.$queryRaw<Result[]>`
SELECT "createdAt" FROM "User"
`
// createdAt is already a Date object
databases
Schema Changes. Reference when using this Prisma feature.
tools
Removed Features. Reference when using this Prisma feature.
tools
Prisma Config. Reference when using this Prisma feature.
tools
ESM Support. Reference when using this Prisma feature.