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

在Prisma ORM的PostgreSQL中使用动态orderBy排序失效问题排查

问题原因

Prisma的$queryRaw会将你拼接的orderBy字符串当作字符串字面量传入SQL,而非解析为排序语法。比如你传的"acceptedInvites" DESC会被转义成'\"acceptedInvites\" DESC',数据库会把这个固定字符串作为排序依据,自然得不到预期的排序结果。

解决方案

使用Prisma提供的sql模板标签和identifier()函数动态生成排序规则,它能正确处理SQL标识符(包括字段别名),同时避免SQL注入风险:

import { sql } from '@prisma/client'; // 需导入sql工具

export const getUsers = async (
  page: number = 1,
  pageSize: number = 10,
  sortField: string = "acceptedInvites",
  sortType: 'asc' | 'desc' = 'desc'
): Promise<any> => {
  try {
    const client = await getClient();
    const skip = (page - 1) * pageSize;
    const total = await client.user.count();

    // 校验合法排序字段,防止非法字段引发SQL错误
    const validSortFields = ['id', 'displayName', 'acceptedInvites', 'invitedBy', 'ranking'];
    if (!validSortFields.includes(sortField)) {
      sortField = 'acceptedInvites'; // 非法字段时用默认值
    }

    const users = await client.$queryRaw`
      SELECT
        "User".id,
        "User"."displayName",
        "User"."avatarUrl",
        "User"."isAvatar",
        COUNT("Referrals".id)::INTEGER as "acceptedInvites",
        "ReferredByUser"."displayName" as invitedBy,
        CAST(RANK() OVER (ORDER BY COUNT("Referrals".id) DESC, "User"."displayName" ASC) AS INTEGER) as ranking
      FROM
        "User"
      LEFT JOIN
        "User" as "Referrals" ON "User"."id" = "Referrals"."referredBy"
      LEFT JOIN
        "User" as "ReferredByUser" ON "User"."referredBy" = "ReferredByUser"."id"
      GROUP BY
        "User".id, "User"."displayName", "ReferredByUser"."displayName"
      ORDER BY ${sql.identifier(sortField)} ${sortType.toUpperCase()}
      OFFSET ${skip}
      LIMIT ${pageSize};
    `;

    return { users, total };
  } catch (error) {
    throw error;
  }
};
关键说明
  • sql.identifier(sortField):将字段名(或别名)转义为合法的SQL标识符,支持带引号的别名如acceptedInvites。
  • 拆分排序字段与方向:分别传入参数,避免拼接字符串导致的转义问题。
  • 字段校验:过滤非法输入,防止SQL语法错误或注入风险。

内容的提问来源于stack exchange,提问作者aleksy

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 22:27:33