如何删除多行数据 - TypeORM、PostgreSQL和Node.js(TypeScript)

7

大家好,这是我的函数,它接收一个id数组,我想一次性删除所有行而不用循环遍历,但是找不到解决方案。希望能得到帮助。

async remove(ids: DeleteEmployeeAnswerDTO): Promise<boolean> {
        if (ids.employeeAnswersIds.length) {
            for (const id of ids.employeeAnswersIds) {
                await EmployeeAnswers.delete(id.id);
            }
        }
        return true;
    }

这是对我有效的方法 https://medium.com/@jimkang/typeorm-delete-multiple-records-6119ff8b740 - frederj
你解决了这个问题吗? - jack.benson
4个回答

9
如果你的表格只有一个 ID 列,那么你可以传递一个 ID 数组:
await EmployeeAnswers.delete(ids.employeeAnswersIds);

您可以在where语句中使用In来指定多个ID
await EmployeeAnswers.delete({ id: In(ids.employeeAnswersIds) });

但是,如果你处理的是一个具有复合主键的表格,就像我的情况一样,下面的示例可能会是适合你的解决方案。我对这个答案不是很满意,但是以下是我如何使用DeleteQueryBuilder (文档)解决了这个问题:

async remove(ids: DeleteEmployeeAnswerDTO): Promise<boolean> {
  if (ids.employeeAnswersIds.length) {
    const deleteQueryBuilder = EmployeeAnswer.createQueryBuilder().delete()

    const idClauses = ids.map((_, index) => `ID = :id${index}`)
    const idClauseVariables = ids.reduce((value: any, id, index) => {
      value[`id${index}`] = id
      return value
    }, {})

    await deleteQueryBuilder.where(idClauses.join(' OR '), idClauseVariables).execute()
  }
  return true;
}

由于提问者提供的示例已经很清楚地表明了他的实体只有一个主键,因此我想强调你提供的最后一个示例。 - csakbalint

0

您可以搜索多个记录,然后在单个操作中删除找到的实体。如果未找到一个或多个实体,则不会删除任何内容。

async removeMany(ids: string[]) {
    const entities = await this.entityRepository.findByIds(ids);
    if (!entities) {
      throw new NotFoundException(`Some Entities not found, no changes applied!`);
    }
    return this.entityRepository.remove(entities);
  }

这个可以工作,但是这个过程包含了一个不必要的查询。如果有大量的id,第一个查询可能会非常慢。 - csakbalint
是的,但根据我的经验,如果提供的ID在表中不存在,删除操作会导致灾难性的失败。服务器就会崩溃……如果你问我,这太疯狂了。您会如何在单个查询中规避此问题?问候 - Sergio Arrighi
据说findByIds已经被弃用了。有一个注释说要与In运算符一起使用findBy。但是到目前为止,我还没有成功地使它工作。 - plutownium
在我的情况下,我之前已经执行了查询,所以删除函数非常好用,谢谢。 - StPaulis

0
之前我也遇到过同样的问题。 如果你使用NestJS + typeorm,我的案例可能会有所帮助。
这是一个模块:
import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';

import { TaskController } from './task.controller';
import { Task } from './task.entity';
import { TaskService } from './task.service';

@Module({
  imports: [TypeOrmModule.forFeature([Task])],
  controllers: [TaskController],
  providers: [TaskService],
  exports: [TaskService],
})
export class TaskModule {}

这是我的控制器的一部分:
import { Controller, Delete, Query, Request } from '@nestjs/common';
import { TaskService } from './task.service';


@Controller('task')
export class TaskController {
  constructor(private taskService: TaskService) {}

  @Delete('/multiple/')
  async deleteMultiple(@Request() req, @Query('ids') ids: string[]) {
    const userId = req.user.id;

    try {
      await this.taskService.deleteMultiple(userId, ids);

      return 'success';
    } catch (error) {
      return 'error';
    }
  }
}

这里有一个服务:
import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { In, Repository } from 'typeorm';

@Injectable()
export class TaskService {
  constructor(@InjectRepository(Task) private repo: Repository<Task>) {}

  async deleteMultiple(userId: string, taskIds: string[]) {
    return await this.repo.delete({ userId, id: In(taskIds) });
  }
}

所以,解决方案是In(taskIds) 希望对某人有用。

1
你的回答可以通过提供更多支持信息来改进。请[编辑]以添加进一步的细节,比如引用或文档,以便他人可以确认你的回答是否正确。你可以在帮助中心找到关于如何撰写良好回答的更多信息。 - Community

-1
使用“clear”方法清除表中记录的所有数据!

async deleteProducts() {
  await this.productRepository.clear();
  return {
    message: MESSAGE.PRODUCTS_REMOVED
  };
}


据说 clear 已经过时了。 - plutownium

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接