2 回答

TA貢獻1865條經驗 獲得超7個贊
這與 postgres 解析器如何解析參數類型有關。我不知道它是如何實現的,但考慮到觀察到的行為,我會假設INSERT
查詢不會失敗,因為很明顯(name,some_other_id) VALUES ($1,$2)
參數應該與目標列$2
具有相同的類型,即 type 。然后,此類型信息也用于查詢部分的表達式。some_other_id
int8
NULLIF
DO UPDATE SET
您還可以通過使用(name) VALUES ($1)
in來測試此假設INSERT
,您將看到 in 中的NULLIF
表達式隨后將以與查詢DO UPDATE SET
中相同的方式失敗。UPDATE
因此UPDATE
查詢失敗,因為沒有足夠的上下文供解析器推斷$2
參數的準確類型。解析器可以用來推斷類型的“最接近”的東西$2
是NULLIF
調用表達式,特別是它使用調用表達式的第二個參數的類型,即0
類型為int4
,然后它使用該類型信息第一個論點,即$2
。
為避免此問題,您應該對無法準確推斷類型的任何參數使用顯式類型轉換。即使用NULLIF($2::int8, 0)
.

TA貢獻1866條經驗 獲得超5個贊
COALESCE(NULLIF($51, CAST(0 AS BIGINT)), object.some_other_id)
五十一?真的嗎?
pq:值“1010101010144”超出整數類型的范圍
請注意,錯誤消息中的數據類型是integer,而不是bigint。
我認為錯誤的原因是顯示代碼不足。于是我拿出一個魔法水晶球,用手傳球。
一個“安裝”端點,它像這樣有效地充當一個 upsert 函數
我還有一個“更新”端點
您是否將端點稱為PostgreSQL 函數(存儲過程)?我想是的。另外 $1, $2 看起來像 PostgreSQL 函數參數。
魔法水晶球說:您有兩個具有不同數據類型參數的 PostgreSQL 函數:
“安裝”端點具有 $2 函數參數作為bigint數據類型。看起來像
CREATE FUNCTION Install(VARCHAR(255), bigint)
“更新”端點具有 $2 函數參數作為整數數據類型,而不是bigint。它看起來像
CREATE FUNCTION Update(VARCHAR(255), integer)
。
最后,我會更容易理解地重寫你的條件:
UPDATE object
SET some_other_id =
CASE
WHEN $2 = 0 THEN object.some_other_id
ELSE $2
END
WHERE name = $1
- 2 回答
- 0 關注
- 181 瀏覽
添加回答
舉報