openlang

总计打印出来是数字粘在一起,不是求和

每日的行都正常(12500、3400、900 won),但 TOTAL 打印出来是 0125003400900 KRW。为什么多了一个 0?

const grand = rows.reduce((acc, r) => acc + r.cents, 0);
console.log(`TOTAL ${won(grand)}`);

tsc 能通过,Postgres 16 跑在 docker 里。reduce 还是一直以来那个写法……

从英语翻译查看原文

后续讨论 10

顺着彼此的依据读下去
  1. 固定链接

    对,基本就是这个原因,0125003400900 就是字符串拼接的结果,pg 把 bigint 和 numeric 作为字符串返回。要么在 reduce 里用 Number(r.cents),要么在查询里用 cents::int 转换(如果值放得下)。如果可能很大,就用 BigInt,最后再格式化。

    从英语翻译查看原文
  2. 固定链接

    没什么问题,你的总计只是非常诚实。Postgres 发的是文本,JavaScript 把它们粘起来。用字符串拼接做会计,tsc 说“看起来没问题”。当然了。

    从英语翻译查看原文
  3. 固定链接

    关于 cents::int 有一点要注意,如果你改在 SQL 里求和,结果又会变回字符串。sum(int) 返回 bigint,sum(bigint) 返回 numeric,驱动把这两种都作为文本给你。所以 Number() 还是要用,只是最后用一次,而不是每行都用。

    在查询里求和仍然是更好的位置,数据库一趟就搞定。聚合函数的返回类型在 Postgres 聚合函数文档 里。

    从英语翻译查看原文
  4. 固定链接

    好笑的是,每日的行看着正常,是因为 won() 对字符串“12500”和数字的格式化结果一样。只有 + 暴露了问题。前面多出来的 0 就是我初始的 0 变成了文本。MDN 的加法运算符页面说得很直白,任意一边是字符串就拼接。这个我是知道的,只是从没在 reduce 里遇到过...

    从英语翻译查看原文

同一个问题的其他角度

  1. rows.Next 返回了 false,错误却不知道去哪了

    一个基于 database/sql 的小工具返回了半个列表。没有报错。代码如下。 context 带了 deadline。取数据到一半 deadline 到了,rows.Next() 返回 false,循环结束,函数把已经收集到的东西加上 nil 一…

    回复 3最近活动 sqlgo
  2. 部分索引与 WHERE 子句中的参数

    我在给课程项目用 Go 写一个小型任务执行器。环境是通过 database/sql 使用 pgx v5,本地 Postgres 16,还有一张约 600 万行的 jobs 表。几乎全是 done,只有几百行是 queued。我给等待中的行建了个部分索…

    回复 10最近活动 sqlgo
  3. SKIP LOCKED 任务队列,以及事务中途挂掉的 worker

    任务队列直接放在表里。一个 worker 用 Python,一个用 Go。BEGIN,然后 SELECT id, payload FROM jobs WHERE status = 'queued' ORDER BY id LIMIT 1 FOR UP…

    回复 5最近活动 sqlgo