NestJS用Prisma查Postgres报string无法分配给TemplateStringsArray|Sql错误如何解决
报错根因
Prisma的$queryRaw方法要求入参为模板字符串标签或者Sql类型实例,你当前直接传入了手动拼接变量后的普通字符串,不符合类型定义,因此触发TS2345报错。同时这种手动拼接SQL参数的写法还存在SQL注入安全风险,本身就不推荐使用。
另外你的SQL语句还有一处逻辑错误:max('writerNumber')中用单引号包裹字段名,会被PostgreSQL识别为普通字符串常量,而不是你想取的writerNumber字段值,查询结果会不符合预期。
修复代码
你可以选择两种写法,都能解决类型报错:
第一种,显式使用Prisma.sql包裹:
import { Prisma } from '@prisma/client'; async findWriterNumber(writerAddress: string): Promise<number> { const maxNumber = await this.prismaService.$queryRaw<{ max: number; }>( Prisma.sql`SELECT coalesce(max("writerNumber") + 1, 0) as max FROM "Work" LEFT OUTER JOIN "WriterID" ON "Work"."id" = "WorkID"."workId" AND "WorkID"."address" = ${writerAddress}`, ); return maxNumber[0].max; }
第二种,直接用模板字符串作为$queryRaw的参数,不需要额外包裹:
async findWriterNumber(writerAddress: string): Promise<number> { const maxNumber = await this.prismaService.$queryRaw<{ max: number; }>`SELECT coalesce(max("writerNumber") + 1, 0) as max FROM "Work" LEFT OUTER JOIN "WriterID" ON "Work"."id" = "WorkID"."workId" AND "WorkID"."address" = ${writerAddress}`; return maxNumber[0].max; }
注意事项
- 不要将拼接好的普通字符串传入
$queryRaw,所有动态变量直接写在模板字符串的${}占位符中,Prisma会自动做参数化转义,既兼容类型要求也避免SQL注入风险 - PostgreSQL中单引号代表字符串值,字段名/表名如果需要转义请使用双引号
- 不需要手动给字符串类型的变量加单引号包裹,Prisma会自动处理参数类型
内容的提问来源于stack exchange,提问作者Vakindu
相关产品推荐
相关产品推荐

