μ ν¨ν μ«μ κ°μ΄ λ΄ μ½μ λ¬Έμ μ§λ£¨νκ² μ°¨λ¨νλ λ¬Έμ κ° λ°μνμ΅λλ€. λμΌν μ«μ κ°μ μ¬μ©νμ¬ λ°μ΄ν°λ² μ΄μ€μ μλ SQL μ½μ μ΄ μλν©λλ€.
μλ SQL μ½μ :
INSERT INTO foo (id, foo_id, timestamp, value, value2)
VALUES ('ff3bd5e2-dbd8-424b-bb4f-455df1fe9f9c', 'b3a0a2c6-3b58-4659-8b4f-9466cede43be',
'2016-11-01T00:00:00+00:00', null, 66666.55);
λ΄ μ½λλ λ€μκ³Ό κ°μ΅λλ€.
const bluebird = require('bluebird');
const sql = require('mssql');
const db = require('./database.js');
sql.Promise = bluebird;
const COLUMNS = {
id: 'id',
foo_id: 'foo_id',
timestamp: 'timestamp',
value: 'value',
value2: 'value2'
};
exports.create = data => {
return db.getConnection()
.then(conn => {
const ps = new sql.PreparedStatement(conn);
ps.input(COLUMNS.id, sql.UniqueIdentifier);
ps.input(COLUMNS.foo_id, sql.UniqueIdentifier);
ps.input(COLUMNS.timestamp, sql.DateTimeOffset(0));
ps.input(COLUMNS.value, sql.Numeric(30, 15));
ps.input(COLUMNS.value2, sql.Numeric(30, 15));
// Have to convert string to JavaScript date for insert to work
data.timestamp = new Date(data.timestamp);
const header = Object.keys(COLUMNS).map(key => COLUMNS[key]).join();
const query = `INSERT INTO foo (${header}) VALUES (@${COLUMNS.id},` +
` @${COLUMNS.foo_id}, @${COLUMNS.timestamp}, @${COLUMNS.value},` +
` @${COLUMNS.value2})`;
return ps.prepare(query)
.then(() => ps.execute(data)
// Releases the connection back to the pool
.then(() => ps.unprepare()))
.then(() => bluebird.resolve());
});
};
μ§λ£¨ν μ½λλ 66666.55λ₯Ό κ°μ΄ 66666550000000000000μΈ μ μλ‘ λ³ννλ κ² κ°μ΅λλ€. κ·Έλ° λ€μ ν΄λΉ κ°μ λλ¨Έμ§μ λͺ«μ μ·¨νμ¬ writeUInt32LEλ₯Ό μ¬μ©νμ¬ λ²νΌμ μ°λ €κ³ ν©λλ€.
μ§λ£¨ν μ½λκ° λΆλ μμμ μ«μλ₯Ό μ μ§νκ³ λ²νΌμ λ΄μ₯ ν¨μ writeDoubleLEλ₯Ό μ¬μ©νλ λμ λΆλ μμμ μ«μλ₯Ό μ μλ‘ λ³ννκ³ λ²νΌμ μ°λ μ΄μ λ 무μμ λκΉ?
μ΄ λ¬Έμ λ‘ μΈν΄ μμΌλ‘ λμκ° μ μμ΅λλ€.
λΆλ μμμ μ«μλ₯Ό μ μλ‘ λ³ννλ μ§λ£¨ν μ½λκ° μ...
μ΄κ²μ΄ TDS νλ‘ν μ½μ΄ μ«μ κ°μ λν΄ μꡬνλ κ²μ΄κΈ° λλ¬Έμ
λλ€.
2.2.5.5.1.6 10μ§μ/μ«μ
sql.Numeric(30, 15)
κ²½μ° _p_λ 30μ΄κ³ _s_λ 15μ
λλ€. λ°λΌμ μ μλ 666666550000000000000(66666.55 * 10^15)μ΄ λλ©° 16λ°μ΄νΈλ‘ νμλμ΄μΌ ν©λλ€.
...
buffer.writeUInt64LE(value); // 8 bytes
buffer.writeUInt32LE(0x00000000); // 4 bytes
buffer.writeUInt32LE(0x00000000); // 4 bytes
첫 λ²μ§Έ μ€μ λ¬Έμ κ° μλ μ€μ λλ€.
https://github.com/tediousjs/tedious/blob/master/src/tracking-buffer/writable-tracking-buffer.js#L125
Buffer.writeInt64LEκ° μμΌλ―λ‘ λ κ°μ 32λΉνΈ μ²ν¬λ‘ μνν΄μΌ ν©λλ€.
writeUInt64LE(value) {
this.writeInt32LE(value & -1);
return this.writeUInt32LE(Math.floor(value * SHIFT_RIGHT_32));
}
32λΉνΈ μ€λ₯Έμͺ½ μννΈλ λ¬Έμ κ° λνλλ κ³³μ
λλ€.
Math.floor(66666550000000000000 * SHIFT_RIGHT_32)
λ 0x39D2F2A02
15522015746
λ₯Ό μ°μΆν©λλ€. 34λΉνΈκ° νμν©λλ€.
μ΄μ λ¬Έμ λ 66666550000000000000μ΄ 0x39d2f2a02aed16000μ΄κ³ 64λΉνΈ μ΄μμ΄ νμνλ€λ κ²μ λλ€. κ·Έλ¬λ μ΄κ²μ 53λΉνΈλ₯Ό μ΄κ³Όνλ λͺ¨λ μ μκ° JavaScriptμ _Number_ μ νμΌλ‘ μ¬λ°λ₯΄κ² ννλ μ μλ κ²μ μλλΌλ λ¬Έμ λ₯Ό μ κΈ°ν©λλ€. μ΄κ²μ μ¬λ°λ₯΄κ² μ²λ¦¬νλ €λ©΄ 머리λ₯Ό κΈμ μ΄λ©° λͺ κ°μ§ μλ‘μ΄ λ¨μ ν μ€νΈκ° νμν μ μμ΅λλ€.
μ΄ λ¬Έμ λ₯Ό ν΄κ²°νλ €λ©΄ λ μμ κ·λͺ¨λ₯Ό μ¬μ©νλ κ²μ΄ μ’μ΅λλ€.
@pekim λ΄ μ§λ¬Έμ λ΅νκ³ μ 보λ₯Ό μ κ³΅ν΄ μ£Όμ μ κ°μ¬ν©λλ€! μμΌλ‘ λμκ°κΈ° μν΄ Node.js λμ PythonμΌλ‘ μμ±νκΈ°λ‘ κ²°μ νμ΅λλ€. λλ μ¬μ ν μ΄ λΌμ΄λΈλ¬λ¦¬λ₯Ό λ€λ₯Έ μμ μ μ¬μ©ν κ²μ΄μ§λ§ μ«μ μ νμ ν¬ν¨νμ§ μμ κ²μ λλ€. λ€λ₯Έ μ¬λμ΄ μ΄ λ¬Έμ μ μ§λ©΄νμ§ μλλ‘ μ루μ μ μ°Ύμ μ μκΈ°λ₯Ό λ°λλλ€.
μ κ²½μ°μλ Numeric
κ° Tedious(Sequelize) μμ λΌμ΄λΈλ¬λ¦¬μ μν΄ μ€μ λμκΈ° λλ¬Έμ λ€λ₯Έ ν΄κ²° λ°©λ²μ μ¬μ©ν΄μΌ νμ΅λλ€. λ³Έμ§μ μΌλ‘ 10μ§μ λ³νμ΄ μ½λκ° μλ λ°μ΄ν°λ² μ΄μ€ λ΄λΆμμ λ°μνλλ‘ λ§€κ°λ³μμ νμμ μ§μ ν©λλ€. λͺ¨λ μ«μμ λν΄ λ€μμ μ¬μ©ν΄μΌ ν©λλ€.
const value_stored = value.toFixed(desired_precision);
μ΄λ μ λ°λλ₯Ό μμ§ μκ³ λ΄κ° μμ§ λͺ»νκ±°λ μ μ΄νμ§ λͺ»νλ κ·λͺ¨μ κ·λͺ¨μ λν κ°μ μ νλ DBμ λ΄ μ½λ μ¬μ΄μ μ무 κ²λ λ°©ν΄νμ§ μλλ‘ νκΈ° μν κ²μ λλ€. λ¬Όλ‘ μ΄κ²μ μ¬λ°λ₯Έ μ νμ μ¬μ©νλ κ²λ³΄λ€ λμν ν¨μ¨μ±μ΄ λ¨μ΄μ§μ§λ§ μ κ²½μ°μλ λ μ½λλΉ <30λ°μ΄νΈ νλν°κ° μ€μνμ§ μμ΅λλ€.
μ κ²½μ°μλ
Numeric
κ° Tedious(Sequelize) μμ λΌμ΄λΈλ¬λ¦¬μ μν΄ μ€μ λμκΈ° λλ¬Έμ λ€λ₯Έ ν΄κ²° λ°©λ²μ μ¬μ©ν΄μΌ νμ΅λλ€. λ³Έμ§μ μΌλ‘ 10μ§μ λ³νμ΄ μ½λκ° μλ λ°μ΄ν°λ² μ΄μ€ λ΄λΆμμ λ°μνλλ‘ λ§€κ°λ³μμ νμμ μ§μ ν©λλ€. λͺ¨λ μ«μμ λν΄ λ€μμ μ¬μ©ν΄μΌ ν©λλ€.const value_stored = value.toFixed(desired_precision);
μ΄λ μ λ°λλ₯Ό μμ§ μκ³ λ΄κ° μμ§ λͺ»νκ±°λ μ μ΄νμ§ λͺ»νλ κ·λͺ¨μ κ·λͺ¨μ λν κ°μ μ νλ DBμ λ΄ μ½λ μ¬μ΄μ μ무 κ²λ λ°©ν΄νμ§ μλλ‘ νκΈ° μν κ²μ λλ€. λ¬Όλ‘ μ΄κ²μ μ¬λ°λ₯Έ μ νμ μ¬μ©νλ κ²λ³΄λ€ λμν ν¨μ¨μ±μ΄ λ¨μ΄μ§μ§λ§ μ κ²½μ°μλ λ μ½λλΉ <30λ°μ΄νΈ νλν°κ° μ€μνμ§ μμ΅λλ€.
κ·Έκ²μ λμκ²λ λ¬Έμ λ₯Ό ν΄κ²°νμ΅λλ€.
μ΄κ²μ μ μμ μΌλ‘ μ μ©ν μ μλ λ°©λ²μ΄ μμ΅λκΉ? λ°λΌμ μ°μμ±μ΄ .toFixed(2)λ₯Ό νΈμΆνλ μμ§μ κ°μ μ½μ /μ λ°μ΄νΈνλ €κ³ ν λλ§λ€?
κ°μ₯ μ μ©ν λκΈ
μ κ²½μ°μλ
Numeric
κ° Tedious(Sequelize) μμ λΌμ΄λΈλ¬λ¦¬μ μν΄ μ€μ λμκΈ° λλ¬Έμ λ€λ₯Έ ν΄κ²° λ°©λ²μ μ¬μ©ν΄μΌ νμ΅λλ€. λ³Έμ§μ μΌλ‘ 10μ§μ λ³νμ΄ μ½λκ° μλ λ°μ΄ν°λ² μ΄μ€ λ΄λΆμμ λ°μνλλ‘ λ§€κ°λ³μμ νμμ μ§μ ν©λλ€. λͺ¨λ μ«μμ λν΄ λ€μμ μ¬μ©ν΄μΌ ν©λλ€.μ΄λ μ λ°λλ₯Ό μμ§ μκ³ λ΄κ° μμ§ λͺ»νκ±°λ μ μ΄νμ§ λͺ»νλ κ·λͺ¨μ κ·λͺ¨μ λν κ°μ μ νλ DBμ λ΄ μ½λ μ¬μ΄μ μ무 κ²λ λ°©ν΄νμ§ μλλ‘ νκΈ° μν κ²μ λλ€. λ¬Όλ‘ μ΄κ²μ μ¬λ°λ₯Έ μ νμ μ¬μ©νλ κ²λ³΄λ€ λμν ν¨μ¨μ±μ΄ λ¨μ΄μ§μ§λ§ μ κ²½μ°μλ λ μ½λλΉ <30λ°μ΄νΈ νλν°κ° μ€μνμ§ μμ΅λλ€.