对于上下文,这个问题发生在我使用默认 postgres 数据库驱动程序编写的 Go 程序中。
我一直在构建一个服务来与一个 postgres 数据库对话,该数据库有一个类似于下面列出的表:
CREATE TABLE object (
id SERIAL PRIMARY KEY NOT NULL,
name VARCHAR(255) UNIQUE,
some_other_id BIGINT UNIQUE
...
);
我为这个项目创建了一些端点,包括一个“安装”端点,它有效地充当了一个 upsert 函数,如下所示:
INSERT INTO object (name, some_other_id)
VALUES ($1, $2)
ON CONFLICT name DO UPDATE SET
some_other_id = COALESCE(NULLIF($2, 0), object.some_other_id)
我还有一个带有如下基础查询的“更新”端点:
UPDATE object
SET some_other_id = COALESCE(NULLIF($2, 0), object.some_other_id)
WHERE name = $1
问题:
每当我运行更新查询时,我总是遇到错误,引用字段“some_other_id”:
pq:值“1010101010144”超出整数类型的范围
但是,即使该行已经存在于数据库中(当它必须评估 COALESCE 语句时),此错误也不会发生在查询的“upsert”版本上。通过将 COALESCE 语句更新为如下所示,我已经能够防止此错误:
COALESCE(NULLIF($2, CAST(0 AS BIGINT)), object.some_other_id)
但由于第一次查询从未发生过这种情况,我想知道这种不一致是否来自我做错了什么或我不明白的事情?还有最好的做法是什么,我应该铸造所有的价值观吗?
我肯定将一个 64 位整数传递给“some_other_id”的查询,即使没有显式类型转换,第一个查询也适用于 Go 实现。
如果需要更多信息(或 Go 实现),请告诉我,非常感谢!(:
编辑:
为了消除混淆,查询直接在 Go 代码中执行,如下所示:
res, err := s.db.ExecContext(ctx, `UPDATE object SET some_other_id = COALESCE(NULLIF($2, 0), object.some_other_id) WHERE name = $1`,
"a name",
1010101010144,
)
两个查询都以完全相同的方式执行。
编辑:还在我当前的解决方法中更正了参数(从$51到$2)。
我还想借此机会指出,该查询确实适用于我提出的修复,这表明问题在于我将 postgres 与NULLIF语句中的类型混淆了?在我的代码和数据库之间没有存储过程要求一个INTEGERarg,至少我已经写过。
莫回无
心有法竹
相关分类