第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號(hào)安全,請(qǐng)及時(shí)綁定郵箱和手機(jī)立即綁定
已解決430363個(gè)問題,去搜搜看,總會(huì)有你想問的

Postgres:使用 NULLIF 時(shí)獲取“...超出整數(shù)類型的范圍”

Postgres:使用 NULLIF 時(shí)獲取“...超出整數(shù)類型的范圍”

Go
胡說叔叔 2022-10-24 15:04:45
對(duì)于上下文,這個(gè)問題發(fā)生在我使用默認(rèn) postgres 數(shù)據(jù)庫驅(qū)動(dòng)程序編寫的 Go 程序中。我一直在構(gòu)建一個(gè)服務(wù)來與一個(gè) postgres 數(shù)據(jù)庫對(duì)話,該數(shù)據(jù)庫有一個(gè)類似于下面列出的表:CREATE TABLE object (    id SERIAL PRIMARY KEY NOT NULL,    name VARCHAR(255) UNIQUE,    some_other_id BIGINT UNIQUE    ...);我為這個(gè)項(xiàng)目創(chuàng)建了一些端點(diǎn),包括一個(gè)“安裝”端點(diǎn),它有效地充當(dāng)了一個(gè) upsert 函數(shù),如下所示: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)我還有一個(gè)帶有如下基礎(chǔ)查詢的“更新”端點(diǎn):UPDATE objectSET some_other_id = COALESCE(NULLIF($2, 0), object.some_other_id)WHERE name = $1問題:每當(dāng)我運(yùn)行更新查詢時(shí),我總是遇到錯(cuò)誤,引用字段“some_other_id”:pq:值“1010101010144”超出整數(shù)類型的范圍但是,即使該行已經(jīng)存在于數(shù)據(jù)庫中(當(dāng)它必須評(píng)估 COALESCE 語句時(shí)),此錯(cuò)誤也不會(huì)發(fā)生在查詢的“upsert”版本上。通過將 COALESCE 語句更新為如下所示,我已經(jīng)能夠防止此錯(cuò)誤:COALESCE(NULLIF($2, CAST(0 AS BIGINT)), object.some_other_id)但由于第一次查詢從未發(fā)生過這種情況,我想知道這種不一致是否來自我做錯(cuò)了什么或我不明白的事情?還有最好的做法是什么,我應(yīng)該鑄造所有的價(jià)值觀嗎?我肯定將一個(gè) 64 位整數(shù)傳遞給“some_other_id”的查詢,即使沒有顯式類型轉(zhuǎn)換,第一個(gè)查詢也適用于 Go 實(shí)現(xiàn)。如果需要更多信息(或 Go 實(shí)現(xiàn)),請(qǐng)告訴我,非常感謝?。ǎ壕庉嫞簽榱讼煜?,查詢直接在 Go 代碼中執(zhí)行,如下所示: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,)兩個(gè)查詢都以完全相同的方式執(zhí)行。編輯:還在我當(dāng)前的解決方法中更正了參數(shù)(從$51到$2)。我還想借此機(jī)會(huì)指出,該查詢確實(shí)適用于我提出的修復(fù),這表明問題在于我將 postgres 與NULLIF語句中的類型混淆了?在我的代碼和數(shù)據(jù)庫之間沒有存儲(chǔ)過程要求一個(gè)INTEGERarg,至少我已經(jīng)寫過。
查看完整描述

2 回答

?
莫回?zé)o

TA貢獻(xiàn)1865條經(jīng)驗(yàn) 獲得超7個(gè)贊

這與 postgres 解析器如何解析參數(shù)類型有關(guān)。我不知道它是如何實(shí)現(xiàn)的,但考慮到觀察到的行為,我會(huì)假設(shè)INSERT查詢不會(huì)失敗,因?yàn)楹苊黠@(name,some_other_id) VALUES ($1,$2)參數(shù)應(yīng)該與目標(biāo)列$2具有相同的類型,即 type 。然后,此類型信息也用于查詢部分的表達(dá)式。some_other_idint8NULLIFDO UPDATE SET

您還可以通過使用(name) VALUES ($1)in來測試此假設(shè)INSERT,您將看到 in 中的NULLIF表達(dá)式隨后將以與查詢DO UPDATE SET中相同的方式失敗。UPDATE

因此UPDATE查詢失敗,因?yàn)闆]有足夠的上下文供解析器推斷$2參數(shù)的準(zhǔn)確類型。解析器可以用來推斷類型的“最接近”的東西$2NULLIF調(diào)用表達(dá)式,特別是它使用調(diào)用表達(dá)式的第二個(gè)參數(shù)的類型,即0類型為int4,然后它使用該類型信息第一個(gè)論點(diǎn),即$2。

為避免此問題,您應(yīng)該對(duì)無法準(zhǔn)確推斷類型的任何參數(shù)使用顯式類型轉(zhuǎn)換。即使用NULLIF($2::int8, 0).


查看完整回答
反對(duì) 回復(fù) 2022-10-24
?
心有法竹

TA貢獻(xiàn)1866條經(jīng)驗(yàn) 獲得超5個(gè)贊

COALESCE(NULLIF($51, CAST(0 AS BIGINT)), object.some_other_id)

五十一?真的嗎?

pq:值“1010101010144”超出整數(shù)類型的范圍

請(qǐng)注意,錯(cuò)誤消息中的數(shù)據(jù)類型是integer,而不是bigint

我認(rèn)為錯(cuò)誤的原因是顯示代碼不足。于是我拿出一個(gè)魔法水晶球,用手傳球。

一個(gè)“安裝”端點(diǎn),它像這樣有效地充當(dāng)一個(gè) upsert 函數(shù)

我還有一個(gè)“更新”端點(diǎn)

您是否將端點(diǎn)稱為PostgreSQL 函數(shù)(存儲(chǔ)過程)?我想是的。另外 $1, $2 看起來像 PostgreSQL 函數(shù)參數(shù)。

魔法水晶球說:您有兩個(gè)具有不同數(shù)據(jù)類型參數(shù)的 PostgreSQL 函數(shù):

  1. “安裝”端點(diǎn)具有 $2 函數(shù)參數(shù)作為bigint數(shù)據(jù)類型。看起來像CREATE FUNCTION Install(VARCHAR(255), bigint)

  2. “更新”端點(diǎn)具有 $2 函數(shù)參數(shù)作為整數(shù)數(shù)據(jù)類型,而不是bigint。它看起來像CREATE FUNCTION Update(VARCHAR(255), integer)。

最后,我會(huì)更容易理解地重寫你的條件:

UPDATE object

SET some_other_id = 

CASE 

WHEN $2 = 0 THEN object.some_other_id

ELSE $2

END

WHERE name = $1


查看完整回答
反對(duì) 回復(fù) 2022-10-24
  • 2 回答
  • 0 關(guān)注
  • 179 瀏覽

添加回答

舉報(bào)

0/150
提交
取消
微信客服

購課補(bǔ)貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動(dòng)學(xué)習(xí)伙伴

公眾號(hào)

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號(hào)