共計 4699 個字符,預計需要花費 12 分鐘才能閱讀完成。
這篇文章主要介紹“PostgreSQL 的數據類型轉換規則有哪些”,在日常操作中,相信很多人在 PostgreSQL 的數據類型轉換規則有哪些問題上存在疑惑,丸趣 TV 小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”PostgreSQL 的數據類型轉換規則有哪些”的疑惑有所幫助!接下來,請跟著丸趣 TV 小編一起來學習吧!
一、函數
函數調用中依賴的指定函數使用以下過程確定.
Function Type Resolution
1. 從 pg_proc 中選擇函數. 通常情況下, 如果不指定 schema, 則在當前搜索路徑中選擇名稱 參數個數匹配的, 否則將選擇指定 schema 的函數.
a. 如在該搜索路徑中存在多個相同參數類型的操作符, 則選擇最早出現的那個. 對于具有不同參數類型的操作符, 無論搜索路徑如何設置, 都被認為是平等的.
b. 如果函數使用 VARIADIC 數組參數聲明, 但調用沒有使用 VARIADIC 關鍵字, 那么數組參數會被替換為數組元素類型的一個或多個值以匹配函數調用. 在這樣展開后, 可能與 NON-VARIADIC 的函數有相同的參數, 在這種情況下, 使用搜索路徑最終出現的那個, 或者使用同一個 schema 中 NON-VARIADIC 的那個.
c. 有默認參數值的函數會匹配任何省略了零個或多個默認參數位置的函數調用. 如果有多個函數匹配, 搜索路徑中最終出現的那個會被選用. 如果在同一個 schema 中存在兩個或以上這樣的函數, 這時候 PG 無法選擇使用哪個, 因此會報錯:”ambiguous function call”.
2. 檢查是否接受輸入的參數類型. 如存在, 則使用此函數. 與操作符類似, 會有安全上的漏洞.
3. 如果沒有完全匹配的函數, 檢查函數調用是否需要類型轉換. 這會出現在函數調用只有一個參數并且函數名稱與內部函數名稱一樣. 此外, 函數參數必須是 unknown-type literal, 或者可 binary-coercible 為命名數據類型, 或者通過 I / O 函數轉換為命名數據類型. 如果滿足這些條件, 那么函數調用會被視為 CAST 的形式.
4. 尋找最佳匹配
參照 operator 操作符的說明.
下面是一些例子:
Round
round 函數在 pg_proc 中的定義如下:
testdb=# select oid,proname,provariadic,proargtypes,prorettype,prosrc from pg_proc where proname = round
oid | proname | provariadic | proargtypes | prorettype | prosrc
------+---------+-------------+-------------+------------+-------------------------------
1342 | round | 0 | 701 | 701 | dround
1707 | round | 0 | 1700 23 | 1700 | numeric_round
1708 | round | 0 | 1700 | 1700 | select pg_catalog.round($1,0)
(3 rows)
其中 proargtypes 是參數類型,prorettype 是返回類型,prosrc 是函數實現”源碼”.
類型 23/701/1700 定義如下
testdb=# select oid,typname,typalign,typstorage from pg_type where oid in (23,701,1700);
oid | typname | typalign | typstorage
------+---------+----------+------------
23 | int4 | i | p
701 | float8 | d | p
1700 | numeric | i | m
(3 rows)
執行 SQL
testdb=# SELECT round(4, 4);
round
--------
4.0000
(1 row)
在 pg_proc 中, 只有一個函數 (oid = 1707) 有兩個參數, 第一個參數類型視為 numeric, 第二個為 integer, 那么第一個參數 4 會自動轉換為 numeric 類型, 該 SQL 語句與”SELECT round(CAST (4 AS numeric), 4);”無異.
Variadic
首先定義一個函數 variadic_example
testdb=# CREATE FUNCTION public.variadic_example(VARIADIC numeric[]) RETURNS int
testdb-# LANGUAGE sql AS SELECT 1
CREATE FUNCTION
函數定義
testdb=# select oid,proname,provariadic,proargtypes,prorettype,prosrc from pg_proc where proname = variadic_example
oid | proname | provariadic | proargtypes | prorettype | prosrc
-------+------------------+-------------+-------------+------------+----------
32787 | variadic_example | 1700 | 1231 | 23 | SELECT 1
(1 row)
testdb=# select oid,typname,typalign,typstorage from pg_type where oid in (1231,1700);
oid | typname | typalign | typstorage
------+----------+----------+------------
1231 | _numeric | i | x
1700 | numeric | i | m
(2 rows)
執行函數, 該函數接受可變參數關鍵字, 但不需要指定, 可允許整數和數值參數:
testdb=# SELECT public.variadic_example(0),
testdb-# public.variadic_example(0.0),
testdb-# public.variadic_example(VARIADIC array[0.0]);
variadic_example | variadic_example | variadic_example
------------------+------------------+------------------
1 | 1 | 1
(1 row)
上述第一次和第二次調用將更傾向明確定義的函數:
testdb=# CREATE FUNCTION public.variadic_example(numeric) RETURNS int
LANGUAGE sql AS SELECT 2
testdb=# CREATE FUNCTION
testdb=# CREATE FUNCTION public.variadic_example(int) RETURNS int
LANGUAGE sql AS SELECT 3
testdb=# CREATE FUNCTION
testdb=# SELECT public.variadic_example(0),
testdb-# public.variadic_example(0.0),
testdb-# public.variadic_example(VARIADIC array[0.0]);
variadic_example | variadic_example | variadic_example
------------------+------------------+------------------
3 | 2 | 1
(1 row)
Substring
有多個 substr 函數:
testdb=# select oid,proname,provariadic,proargtypes,prorettype,prosrc from pg_proc where proname = substr
oid | proname | provariadic | proargtypes | prorettype | prosrc
------+---------+-------------+-------------+------------+---------------------
877 | substr | 0 | 25 23 23 | 25 | text_substr
883 | substr | 0 | 25 23 | 25 | text_substr_no_len
2085 | substr | 0 | 17 23 23 | 17 | bytea_substr
2086 | substr | 0 | 17 23 | 17 | bytea_substr_no_len
(4 rows)
testdb=# select oid,typname,typalign,typstorage from pg_type where oid in (17,23,25);
oid | typname | typalign | typstorage
-----+---------+----------+------------
17 | bytea | i | x
23 | int4 | i | p
25 | text | i | x
(3 rows)
如未指定參數類型調用函數, 系統會優先選擇參數為 text + int4 的函數:
testdb=# SELECT substr(1234 , 3);
substr
--------
34
(1 row)
如指定類型為 varchar, 則轉換為 text
testdb=# SELECT substr(varchar 1234 , 3);
substr
--------
34
(1 row)
testdb=# SELECT substr(CAST (varchar 1234 AS text), 3);
substr
--------
34
(1 row)
如第一個參數為 integer, 系統無轉換函數, 則會報錯
testdb=# SELECT substr(1234, 3);
psql: ERROR: function substr(integer, integer) does not exist
LINE 1: SELECT substr(1234, 3);
^
HINT: No function matches the given name and argument types. You might need to add explicit type casts.
testdb=#
到此,關于“PostgreSQL 的數據類型轉換規則有哪些”的學習就結束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續學習更多相關知識,請繼續關注丸趣 TV 網站,丸趣 TV 小編會繼續努力為大家帶來更多實用的文章!