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

如何在Prisma中无需原生查询实现WHERE子句字符串拼接查询?

在Prisma中实现字符串拼接条件查询(无需原生SQL)

你当前用原生SQL通过拼接国家码和手机号查询数据的逻辑是:

SELECT * FROM tbl_country, tbl_user WHERE CONCAT(tbl_country.code, '-', tbl_user.phone) = '+976-00000000';

对应的表结构:

tbl_country表

idnamecode
1Afghanistan+93
2Aland Islands+358
3Albania+355
.........
240Yemen+967
241Zambia+260
242Zimbabwe+263

tbl_user表

idnamephone
1John Doe11111111
2Bob Doe22222222
3Adam Doe33333333
.........
8Jane Doe88888888
9Tom Doe99999999
10Thomas Doe00000000

解决方案:拆分目标字符串替代拼接查询

Prisma的类型安全查询API不支持直接在where条件中使用字符串拼接函数,但我们可以反向处理:把目标拼接字符串拆分为country.code和user.phone对应的子串,再分别作为过滤条件,完全替代原生SQL的逻辑。

实现代码(NestJS + Prisma)

import { Injectable, BadRequestException } from '@nestjs/common';
import { PrismaService } from './prisma.service';

@Injectable()
export class UserService {
  constructor(private readonly prisma: PrismaService) {}

  async getByFullPhone(fullPhone: string) {
    // 拆分完整号码,校验格式
    const dashIndex = fullPhone.indexOf('-');
    if (dashIndex === -1) {
      throw new BadRequestException('号码格式错误,需包含"-"分隔国家码与手机号');
    }

    const countryCode = fullPhone.slice(0, dashIndex);
    const phoneNumber = fullPhone.slice(dashIndex + 1);

    // 方案1:已定义表关联(推荐)
    // 假设Prisma Schema中tbl_user已关联tbl_country(如通过countryId外键)
    const matchedData = await this.prisma.tbl_user.findMany({
      include: {
        // 关联的国家表字段名,需与Prisma Schema定义一致
        country: {
          where: { code: countryCode },
        },
      },
      where: { phone: phoneNumber },
      // 过滤掉未匹配到对应国家的用户
      having: { country: { isNot: null } },
    });

    // 方案2:未定义表关联(适配原SQL笛卡尔积逻辑)
    // const countries = await this.prisma.tbl_country.findMany({
    //   where: { code: countryCode },
    // });
    // const users = await this.prisma.tbl_user.findMany({
    //   where: { phone: phoneNumber },
    // });
    // // 生成所有符合条件的国家-用户组合
    // const matchedData = countries.flatMap(country => 
    //   users.map(user => ({ ...country, ...user }))
    // );

    return matchedData;
  }
}

说明

  1. 方案1基于表关联实现,查询效率更高,且符合ORM的设计规范,优先推荐使用。需要提前在Prisma Schema中定义tbl_user与tbl_country的关联关系,例如:
model tbl_user {
  id      Int      @id @default(autoincrement())
  name    String
  phone   String
  countryId Int
  country tbl_country @relation(fields: [countryId], references: [id])
}

model tbl_country {
  id    Int      @id @default(autoincrement())
  name  String
  code  String   @unique
  users tbl_user[]
}
  1. 方案2适配原SQL的笛卡尔积逻辑,无需表关联,但查询效率较低,仅在无法修改Schema的场景下使用。

内容的提问来源于stack exchange,提问作者Enkh-Amar Ganbat

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 17:20:37