【发布时间】:2019-07-07 16:04:18
【问题描述】:
我在 NodeJs 中使用 Sequelize ORM 连接到 MSSQL 服务器。
最近我遇到了一个问题,当通过 sequelize 读取时,一个特定的值会以不同的方式表示。该值为9xxxxxxx9.0000000000
例如:假设值为999999999.0000000000
当通过 sequelize 读取时,值为 999999999.0000001
在 Sequelize 中,模型的类型为 DataTypes.INTEGER,而 allowNull 为 true
我也为 Sequelize 创建了错误,但如果有人也可以在这里帮助我,那就太好了。 https://github.com/sequelize/sequelize/issues/11131
我已经尝试了许多版本的 Sequelize,包括最新版本,但问题仍然存在。我尝试了不同的值集,例如 8 乘以 9,它会正确返回值。仅当位数为 9 且 number 以数字 9 开头和结尾时才会出现问题。
NodeJS 中的 Sequelize 模型
function getModel(dBSequelize, DataTypes) {
const model = dBSequelize.define(
'testtable',
// attributes
{
Id: {
type: DataTypes.INTEGER,
allowNull: false,
primaryKey: true,
autoIncrement: true
},
Quantity: {
type: DataTypes.INTEGER,
allowNull: true
}
},
// options
{
schema: 'dbo',
freezeTableName: true,
tableName: 'TestTable',
timestamps: false
});
return model;
}
module.exports = getModel;
使用 sequelize 读取值
async getData(context) {
try {
const connection = await dbFactory.getTediousConnection();
var query = "select Quantity from dbo.[TestTable]"
const response = await connection.execSql(query);
connection.close();
return response;
}
catch (error) {
}
}
你期望会发生什么? 999999999
实际发生了什么? 999999999.0000001
【问题讨论】:
-
不过,根据您的链接问题,数据类型不是整数,而是
DECIMAL(28, 10),因此至少您要求进行转换最好在数据库本身中执行 (select convert(int, quantity) as quantity)。问题不在于 Sequelize,而在于 Tedious,特别是 this。它计算9999999990000000000 / Math.pow(10, 10),其结果并不完全是999999999。 JavaScript 不是精确数字的好语言。 -
“修复”这个问题,从要求 Tedious 至少转换每个具有精确表示的值的意义上来说是可能的(
999999999确实有一个精确的表示为Number)是可能的理论上,但不是特别简单。这也不会真正解决适合DECIMAL(28, 10)的值的问题,但没有精确表示为Number(如999999999.0000000001),所以它充其量只能掩盖真正的问题(我们是不使用真正的 base 10 类型)。 -
我想也可以考虑对 Sequelize 进行“修复”,尽管有基础数据,但它会将数值转换为指定的数据模型“类型”,方法是将它们四舍五入到最接近的整数值。这在所有情况下也不是一个完美的解决方案,因为隐式舍入会带来固有的麻烦——
999999999.5应该变成999999999还是1000000000?但是,如果您始终通过INT镜头访问DECIMAL,它将解决此问题。
标签: node.js sequelize.js