NestJS使用TypeORM向SQL Server插入bigint类型数据报错如何解决?
问题根因
这个报错是SQL Server的Node驱动tediious的校验规则触发的:
默认情况下,驱动会把bigint类型的值尝试转为JavaScript的Number类型处理,但JS的Number安全整数范围是[-2^53, 2^53]也就是报错里提到的-9007199254740991 ~ 9007199254740991,如果你的CatID数值超出这个范围,就会触发校验失败。哪怕你实体里定义了id是string类型,TypeORM默认还是会将bigint字段的值转为数字传给驱动,因此触发报错。
解决方法
可以根据你的业务场景选以下任意一种方案:
方案1:单字段配置转换器(仅针对Cats表的CatID字段)
在CatsEntity的id字段的@Column配置中添加转换器,明确告诉TypeORM将该字段作为字符串处理,不做数字转换:
import { Column, Entity } from 'typeorm'; @Entity('Cats') export class CatsEntity { @Column({ type: 'bigint', name: 'CatID', // 新增转换器 transformer: { // 从数据库查询时,将返回的bigint转为字符串 from: (val: number | string) => val?.toString() || '', // 写入数据库时,直接透传字符串值给驱动 to: (val: string) => val } }) public id: string; // 其余字段保持不变 @Column('int', { primary: true, name: 'CatDB' }) public db: number; @Column('varchar', { name: 'Name' }) public name: string; @Column('datetime', { name: 'DDB_LAST_MOD' }) public ddbLastMod: Date; }
方案2:全局配置bigint转字符串(项目所有bigint字段都按字符串处理)
在NestJS的TypeORM连接配置中,添加MSSQL驱动的bigNumberStrings配置项,全局生效:
// typeorm.config.ts 或AppModule中导入TypeORM的配置 TypeOrmModule.forRoot({ type: 'mssql', host: '你的数据库地址', port: 1433, username: '用户名', password: '密码', database: '库名', // 新增驱动配置 options: { trustServerCertificate: true, // 所有bigint类型都按字符串处理 bigNumberStrings: true }, entities: [__dirname + '/**/*.entity{.ts,.js}'], synchronize: false })
可选优化:增加DTO参数校验
可以给InsertCatsDto增加参数校验,避免传入非数字格式的id字符串:
import { IsNumberString, IsInt, IsNotEmpty, IsString } from 'class-validator'; export class InsertCatsDto { @IsNotEmpty() @IsNumberString() // 校验值为数字格式的字符串 public id: string; @IsNotEmpty() @IsInt() public db: number; @IsNotEmpty() @IsString() public name: string; }
记得开启NestJS的全局ValidationPipe才能让校验生效,在main.ts中添加:
import { ValidationPipe } from '@nestjs/common'; async function bootstrap() { const app = await NestFactory.create(AppModule); app.useGlobalPipes(new ValidationPipe()); await app.listen(3000); } bootstrap();
内容的提问来源于stack exchange,提问作者Serhii G.
相关产品推荐
相关产品推荐

