tedious
tedious copied to clipboard
writeParameterData with a large scale value won't write correct buffer value
writeParameterData with { precision:30, scale:15, value:43069.0122916667 }
will generate a wrong buffer value. see the unit test.
it.only('correctly converts 'number' values (Precision > 28 and scale 15)', function() {
const value = 43069.0122916667;
const expected = Buffer.from('11013be3c8dbb58701000000000000000000', 'hex');
const precision = 30;
const type = TYPES.Decimal;
const parameterValue = { value, precision, scale: 15 };
const buffer = Buffer.concat([...type.generateParameterData(parameterValue, { useUTC: false })]);
assert.deepEqual(buffer, expected);
});
Basically, the following will generate a number larger than int64 max
const value = Math.round(Math.abs(parameter.value * Math.pow(10, parameter.scale)));
I'm not sure if the following code should handle the number or not
else {
buffer.writeUInt8(17);
buffer.writeUInt8(sign);
buffer.writeUInt64LE(value);
buffer.writeUInt32LE(0x00000000);
buffer.writeUInt32LE(0x00000000);
}
Hi @MartinJLee, this is a known issue. Checkout #678.
The issue is that Many (but not all) of the data types supported in SQL Server do not map 1:1 to JavaScript types
. This happens especially with large precision and scale, in which case the calculated value
goes beyond what JavaScript can handle.
For e.g., the value you want to store is 43069012291666710000
, but JavaScript / Node.js can only handle up to 9007199254740991
. We will re-focus on #678 to see what changes we can make to mitigate this issue.
For now you could try to use the library big-number