Postgresql

Postgres 函式是否應該返回/強制數字比例/精度?

  • November 23, 2020

以下函式返回兩個通用數字,而不是我想我在函式返回定義中指定的 numeric(20,10)。這是出乎意料的(我)。有沒有辦法確保函式對 numeric(20,10) 執行“強制”,因此外部程式碼不必強制轉換?

drop function test_numeric;
CREATE OR REPLACE FUNCTION test_numeric ()
RETURNS TABLE(m numeric(20,10), n numeric(20,10)) AS $$
-- RETURNS TABLE(m numeric, n numeric) AS $$
BEGIN
   RETURN QUERY
   select
       -- returned as written (with more than 10 decimal places)
       88888888.88888888888888888 as mm,
       -- truncated as expected
       88888888.88888888888888888::numeric(20,10) as nn;
END;
$$ LANGUAGE plpgsql;

$$ Edit based on feedback in answers $$這是一個小提琴,展示了函式簽名如何不強制返回類型(希望)。M是點。即使簽名說我們正在返回一個數字(20,10),一個通用數字也會被返回。問題是當後續程式碼需要數字(20,10)但類型是數字時(在創建或更新視圖/表等時出現)。最出乎意料的是,函式簽名基本上被忽略或被程式碼覆蓋,下一個使用者看到函式簽名,期望 20/10 並得到完全不同的東西。 小提琴

另一個小提琴表明指定返回的比例或精度完全無關緊要。可以返回任何數字比例/精度,並將保持它在函式體內的比例或精度。

小提琴

$$ Further Edit $$很抱歉打了馬並證明了我對數字類型的誤解。但是,如果在更改此視圖時比例和精度很重要,那麼很難理解為什麼在定義函式將返回的表時它並不重要。如果 numeric(20,10) 是 numeric 的子類型,並且如果我指定要返回的 numeric 可以傳遞,我也許可以理解。只是從來沒有聽說過一些不太具體的東西傳遞給指定為更具體的東西(在強類型語言中)。 小提琴

RETURNS TABLE(m numeric(20,10), n numeric(20,10))不強制返回列的數據類型**;**它只是一個聲明,元數據旨在通知呼叫者函式應該返回什麼。聲明不能不需要任何東西,它是函式實現要實現的“承諾”。函式程式碼本身負責它返回的內容。換句話說,您必鬚根據需要在函式體中使用顯式類型轉換。

如果函式沒有履行承諾,那就是實現錯誤。


PS查看原始碼coerce_type它只是比較類型OID,因此任何numeric其他都兼容numeric


   if (targetTypeId == inputTypeId ||
       node == NULL)
   {
       /* no conversion needed */
       return node;
   }

引用自:https://dba.stackexchange.com/questions/280182