Postgresql

如何在 PostgreSQL 中使用數組作為 VARIADIC 函式的參數?

  • September 10, 2021

我正在嘗試json_extract_path_text()使用citext模組製作不區分大小寫的版本。

我希望這是一個簡單的內置函式包裝器,唯一的區別是它接受citext作為第一個參數而不是json. 我希望這是對本機實現的直接傳遞,只需事先進行類型轉換。這是我到目前為止所擁有的:

create extension citext;

create or replace function json_extract_path_text ( string citext, variadic params text[]) RETURNS text IMMUTABLE AS
$$
   BEGIN
       SELECT json_extract_path_text(string::json, params);
   END;
$$
LANGUAGE 'plpgsql';

但是,由於類型不匹配,這不能正常工作:

ERROR:  function json_extract_path_text(json, text[]) does not exist
LINE 1: SELECT json_extract_path_text(string::json, params)
               ^
HINT:  No function matches the given name and argument types. You might need to add explicit type casts.
QUERY:  SELECT json_extract_path_text(string::json, params)
CONTEXT:  PL/pgSQL function json_extract_path_text(citext,text[]) line 3 at SQL statement

我嘗試過使用動態字元串構造和破解解決方案EXECUTE,但這確實很麻煩,我覺得必須有一種更簡潔的方法將VARIADIC參數傳遞給內部函式。但是,我看不到任何明顯的方法。我怎樣才能做到這一點?

使用呼叫中的關鍵字按原樣傳遞數組:VARIADIC

CREATE OR REPLACE FUNCTION json_extract_path_text(string citext, VARIADIC params text[])
 RETURNS text LANGUAGE sql IMMUTABLE PARALLEL SAFE AS
'SELECT json_extract_path_text(string::json, **VARIADIC** params)';

稱呼:

SELECT json_extract_path_text('{"f1":{"f2":1,"f3":"foo"}}', VARIADIC '{f1, f3}');
 json_extract_path_text
----------------------
 foo

PARALLEL SAFE對於 Postgres 9.6 或更高版本。

手冊VARIADIC

有時能夠將已經構造的數組傳遞給可變參數函式很有用;當一個可變參數函式想要將其數組參數傳遞給另一個時,這特別方便。您可以通過VARIADIC在呼叫中指定來做到這一點:

SELECT mleast(VARIADIC ARRAY[10, -1, 5, 4.4]);

更多細節:

需要明確的是:在函式內部,VARIADIC參數只是另一個數組,沒有什麼特別之處。VARIADIC在兩個單獨的函式定義中使用會使情況有點混亂。解決方案是在函式呼叫VARIADIC中為相關但不同的目的使用相同的關鍵字。不要更加困惑。

旁白:不要引用語言名稱,它是一個標識符。

不區分大小寫的版本,帶有citext?

我正在嘗試json_extract_path_text()使用 citext 模組製作不區分大小寫的版本。

雖然上述功能有效,但它根本不區分大小寫。保留原始輸入,該輸入通過強制轉換為(or )citext恢復並且可以混合大小寫。text``json

我不會用citext開始。各種極端情況問題:

出於您的目的,我建議呼叫內置json_extract_path_text()with lower(citext_value),它返回小寫text,並將第二個參數(“路徑元素”)小寫,以使其實際上不區分大小寫:

SELECT json_extract_path_text(lower('{"F1":{"f2":1,"f3":"foo"}}'::citext)::json
                           , VARIADIC lower('{f1, F3}')::text[]);

注意轉換為text[]after lower()

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