You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.30 07:48:01