在多行更新中強制轉換NULL 類型
在PostgreSQL 中,在多行上執行更新查詢可能會導致處理NULL 時出錯如果未明確轉換列類型的值。本文探討了此問題的幾種解決方案,提供了替代方法來確保多行更新期間正確的類型轉換。
解決方案1:使用VALUES 和UNION ALL 選擇Limit 0
UPDATE foo f SET x = t.x , y = t.y FROM ( (SELECT pkid, x, y FROM foo LIMIT 0) -- Get column types UNION ALL VALUES (1, 20, NULL) -- No type casts , (2, 50, NULL) ) t -- Column names and types defined WHERE f.pkid = t.pkid;
此方法結合了LIMIT 為0 的SELECT 語句來擷取欄位名稱與類型,然後使用UNION ALL 運算子。子查詢的第一行確保為後續行定義適當的列類型。
解決方案2:使用VALUES 和UNION ALL SELECT 選擇Limit 0
UPDATE foo f SET x = t.x , y = t.y FROM ( (SELECT pkid, x, y FROM foo LIMIT 0) -- Get column types UNION ALL SELECT 1, 20, NULL UNION ALL SELECT 2, 50, NULL ) t -- Column names and types defined WHERE f.pkid = t.pkid;
與解決方案1 類似,此方法使用SELECT 取得列類型,然後使用單獨的SELECT語句附加資料行,防止任何過早類型
解決方案3:具有每列類型的VALUES 表達式
UPDATE foo f SET x = t.x , y = t.y FROM ( VALUES ((SELECT pkid FROM foo LIMIT 0) , (SELECT x FROM foo LIMIT 0) , (SELECT y FROM foo LIMIT 0)) -- Get type for each col individually , (1, 20, NULL) , (2, 50, NULL) ) t (pkid, x, y) -- Columns names not defined yet, only types. ...
此解決方案定義VALUES 表達式定義本身中的列類型,確保後續行由於自動類型假設,被轉換為這些類型而不會遇到任何錯誤。
解決方案4:具有行類型的VALUES 表達式
UPDATE foo f SET x = (t.r).x -- Parenthesis for unambiguous syntax , y = (t.r).y FROM ( VALUES ('(1,20,)'::foo) -- Columns need to be in table default order ,('(2,50,)') -- Nothing after last comma for NULL ) t (r) -- Column name for row type WHERE f.pkid = (t.r).pkid;
此方法使用特定表的行類型,可讓您將列隱式轉換為正確的類型。您可以使用欄位選擇語法存取各個列值。
解 5:具有分解行類型的 VALUES 表達式
UPDATE foo f SET x = t.x , y = t.y FROM ( VALUES (('(1,20,)'::foo).*) -- Decomposed row of values , (2, 50, NULL) ) t(pkid, x, y) -- Arbitrary column names (match table columns) WHERE f.pkid = t.pkid; -- Eliminates 1st row with NULL values
與解決方案 4 類似,但使用分解行指定資料值。這允許您僅提供相關列,而無需了解表中所有列的完整順序和類型。
選擇最佳解決方案取決於效能、便利性和可用性等因素有關列類型的信息。
以上是如何處理 PostgreSQL 多行更新中的 NULL 類型轉換?的詳細內容。更多資訊請關注PHP中文網其他相關文章!