W3Cschool
恭喜您成為首批注冊用戶
獲得88經(jīng)驗值獎勵
CREATE CAST — 定義一種新的造型
CREATE CAST (source_type
AStarget_type
) WITH FUNCTIONfunction_name
[ (argument_type
[, ...]) ] [ AS ASSIGNMENT | AS IMPLICIT ] CREATE CAST (source_type
AStarget_type
) WITHOUT FUNCTION [ AS ASSIGNMENT | AS IMPLICIT ] CREATE CAST (source_type
AStarget_type
) WITH INOUT [ AS ASSIGNMENT | AS IMPLICIT ]
CREATE CAST
定義一種新的造型。 一種造型指定如何在兩種數(shù)據(jù)類型之間執(zhí)行轉(zhuǎn)換。例如,
SELECT CAST(42 AS float8);
通過調(diào)用一個之前指定的函數(shù)(這種情況中是 float8(int4)
)把整型常量 42 轉(zhuǎn)換成類型 float8
(如果沒有定義合適的造型, 該轉(zhuǎn)換會失?。?/p>
兩種類型可以是二進(jìn)制可強(qiáng)制,這表示該轉(zhuǎn)換 可以被“免費(fèi)”執(zhí)行而不用調(diào)用任何函數(shù)。這要求相應(yīng)的 值使用同樣的內(nèi)部表示。例如,類型text
和 varchar
在雙向都是二進(jìn)制可強(qiáng)制的。二進(jìn)制可強(qiáng)制性并 不必是一種對稱關(guān)系。例如,在當(dāng)前實現(xiàn)中從
xml
到 text
的造型可以被免費(fèi)執(zhí)行,但是反向則需要一個函數(shù)來 執(zhí)行至少一次語法檢查(兩種在雙向都二進(jìn)制值兼容的類型也被稱作二進(jìn) 制兼容)。
通過使用WITH INOUT
語法,你可以把一種造型定義 成I/O 轉(zhuǎn)換造型。一種 I/O 轉(zhuǎn)換造型執(zhí)行時,會調(diào)用源 數(shù)據(jù)類型的輸出函數(shù),并且把結(jié)果字符串傳遞給目標(biāo)數(shù)據(jù)類型的輸入函數(shù)。 在很多常見情況中,這種特性避免了為轉(zhuǎn)換單獨(dú)定義一個造型函數(shù)。一種 I/O 轉(zhuǎn)換造型表現(xiàn)得和一個常規(guī)的基于函數(shù)的造型相同,只是實現(xiàn)不同而已。
默認(rèn)情況下,只有一次顯式造型請求才會調(diào)用造型, 形式是CAST(
or x
AS typename
)x
::
typename
。
如果造型被標(biāo)記為AS ASSIGNMENT
,那么在為一個目標(biāo)數(shù)據(jù) 類型的列賦值時會隱式地調(diào)用它。例如,假設(shè)foo.f1
是 一個類型text
的列,那么如果從類型integer
到類型text
的造型被標(biāo)記為AS ASSIGNMENT
,
則:
INSERT INTO foo (f1) VALUES (42);
將被允許,否則不會允許(我們通常使用賦值造型 來描述此類造型)。
如果造型被標(biāo)記為AS IMPLICIT
,那么可以在任何上下文 中隱式地調(diào)用它,無論是賦值還是在一個表達(dá)式內(nèi)部(我們通常用術(shù)語 隱式造型來描述這類造型)。例如,考慮這個 查詢:
SELECT 2 + 4.0;
解析器初始會把常量分別標(biāo)記為類型integer
和 numeric
。在系統(tǒng)目錄中沒有integer
+
numeric
操作符,但是有一個 numeric
+
numeric
操作符。 因此,如果有一種可用的從integer
到 numeric
的造型且被標(biāo)記為AS IMPLICIT
— 實際上確實有 — 該查詢將會成功。解析器將應(yīng)用該隱式造型 并且解決該查詢,就好像它被寫成:
SELECT CAST ( 2 AS numeric ) + 4.0;
現(xiàn)在,系統(tǒng)目錄也提供一種從numeric
到integer
的造型。如果這種造型被標(biāo)記為AS IMPLICIT
— 實際上并沒有 — 那么解析器將面臨選擇:是用前面介紹的過程, 還是把numeric
常量造型成integer
并且應(yīng)用
integer
+
integer
操作符。由于 缺少哪種選擇更好的知識,解析器會放棄并且說明查詢有歧義。我們能 告訴解析器把一個混合了numeric
和integer
的 表達(dá)式解析成numeric
更好的方法就是只讓這兩種造型中的
一個是隱式的,沒有有關(guān)于此的內(nèi)建知識。
對標(biāo)記造型為隱式持保守態(tài)度是明智的。過多的隱式造型路徑可能導(dǎo)致 PostgreSQL以令人吃驚的方式解 釋命令,或者由于有多種可能解釋而根本無法解析命令。一種好的經(jīng)驗 是讓一種造型只對于同一種一般類型分類中的類型間的信息保持轉(zhuǎn)換隱式 可調(diào)用。例如,從int2
到int4
的造型 可以被合理地標(biāo)記為隱式,但是從float8
到
int4
的造型可能應(yīng)該只能在賦值時使用??珙愋头诸?的造型(如text
到int4
)最好只被用于顯式使用。
有時為了可用性或者標(biāo)準(zhǔn)兼容的原因,有必要提供在一個類型集合之間 的多種隱式造型,這會導(dǎo)致上述不可避免的歧義。解析器還有一招基于 類型分類和優(yōu)先類型的后手,它能幫助 提供這類情況下預(yù)期的行為。詳見 CREATE TYPE。
要創(chuàng)建一種造型,你必須擁有源數(shù)據(jù)類型和目標(biāo)數(shù)據(jù)類型并且具有在其他類型上 的USAGE
特權(quán)。要創(chuàng)建一種二進(jìn)制可強(qiáng)制造型,你必須是一 個超級用戶(這種限制是因為錯誤的二進(jìn)制可強(qiáng)制造型轉(zhuǎn)換很容易讓服務(wù)器崩潰)。
source_type
該造型的源數(shù)據(jù)類型的名稱。
target_type
該造型的目標(biāo)數(shù)據(jù)類型的名稱。
function_name
[(argument_type
[, ...])]
被用于執(zhí)行該造型的函數(shù)。函數(shù)名稱可以用模式限定。如果沒有被限定, 將在模式搜索路徑中查找該函數(shù)。函數(shù)的結(jié)果數(shù)據(jù)類型必須是該造型的 目標(biāo)數(shù)據(jù)類型。它的參數(shù)討論如下。 如果沒有指定參數(shù)列表,則該函數(shù)名稱在其模式中必須是唯一的。
WITHOUT FUNCTION
指示源類型可以二進(jìn)制強(qiáng)制到目標(biāo)類型,因此執(zhí)行該造型不需要函數(shù)。
WITH INOUT
指示該造型是一種 I/O 轉(zhuǎn)換造型,執(zhí)行需要調(diào)用源數(shù)據(jù)類型的輸出函數(shù), 并且把結(jié)果字符串傳遞給目標(biāo)數(shù)據(jù)類型的輸入函數(shù)。
AS ASSIGNMENT
指示該造型可以在賦值的情況下被隱式調(diào)用。
AS IMPLICIT
指示該造型可以在任何上下文中被隱式調(diào)用。
造型實現(xiàn)函數(shù)可以具有 1 到 3 個參數(shù)。第一個參數(shù)類型必須等于源類型或者 能從源類型二進(jìn)制強(qiáng)制得到。第二個參數(shù)(如果存在)必須是類型 integer
,它接收與目標(biāo)類型相關(guān)聯(lián)的類型修飾符,如果沒有類型 修飾符,它會收到-1
。第三個參數(shù)(如果存在)必須是類型 boolean
,如果該造型是一種顯式造型,它會收到 true
,否則會收到
false
(奇怪地是,SQL 標(biāo)準(zhǔn)在 某些情況中對顯式和隱式造型要求不同的行為。這個參數(shù)被提供給必須實現(xiàn)這 類造型的函數(shù)。不推薦在設(shè)計自己的數(shù)據(jù)類型時用它)。
一個造型函數(shù)的返回類型必須等于目標(biāo)類型或者能二進(jìn)制強(qiáng)制到目標(biāo)類型。
通常,強(qiáng)制轉(zhuǎn)換必須具有不同的源和目標(biāo)數(shù)據(jù)類型。但是,如果它有一個帶有多個參數(shù)的強(qiáng)制轉(zhuǎn)換實現(xiàn)函數(shù),則可以聲明具有相同源類型和目標(biāo)類型的造型。它用于表示系統(tǒng)目錄中特定類型的長度強(qiáng)制函數(shù)。命名函數(shù)用于將類型的值強(qiáng)制轉(zhuǎn)為其第二個參數(shù)提供的類型修飾符的值。
當(dāng)強(qiáng)制轉(zhuǎn)換具有不同的源類型和目標(biāo)類型,并且一個函數(shù)使用多個參數(shù)時,它支持從一種類型轉(zhuǎn)換為另一種類型,并在單個步驟中應(yīng)用長度強(qiáng)制。如果沒有這樣的條目,強(qiáng)制轉(zhuǎn)換為使用類型修飾符的類型將涉及兩個強(qiáng)制轉(zhuǎn)換步驟,一個是在數(shù)據(jù)類型之間進(jìn)行轉(zhuǎn)換,另一個是應(yīng)用修飾符。
向域類型強(qiáng)制轉(zhuǎn)換或從域類型強(qiáng)制轉(zhuǎn)換當(dāng)前無效。向域或從域強(qiáng)制轉(zhuǎn)換使用與其基礎(chǔ)類型關(guān)聯(lián)的造型。
使用DROP CAST移除用戶定義的造型。
記住如果你想要能夠雙向轉(zhuǎn)換類型,你需要在兩個方向上都 顯式聲明造型。
通常沒有必要創(chuàng)建用戶定義類型和標(biāo)準(zhǔn)字符串類型(text
、 varchar
和char(
, 以及被定義在字符串分類中的用戶定義類型)之間的造型。 PostgreSQL會為它們提供自動的 I/O 轉(zhuǎn)換造型。 到字符串類型的自動造型被當(dāng)做賦值造型,而字符串類型作為源的自動 造型只能是顯式的。通過聲明你自己的造型來替換自動造型可以覆蓋這 種行為,但是這樣做的唯一原因是你想讓該轉(zhuǎn)換比標(biāo)準(zhǔn)的設(shè)置更容易被 調(diào)用。另一種可能的原因是你想讓該轉(zhuǎn)換的行為與該類型的 I/O 函數(shù)不 同,但這種原因足夠令人感到意外,你應(yīng)該考慮再三它是不是個好主意
(確實有少量內(nèi)建類型對轉(zhuǎn)換具有不同的行為,絕大部分是因為 SQL 標(biāo)準(zhǔn)的要求)。n
)
雖然不必要,推薦你繼續(xù)遵循這種在目標(biāo)數(shù)據(jù)類型后面命名造型 實現(xiàn)函數(shù)的習(xí)慣。很多用戶習(xí)慣于能夠使用一種函數(shù)風(fēng)格的記法來造型 數(shù)據(jù)類型,即typename
(x
)。 這種記法正好是對造型實現(xiàn)函數(shù)的調(diào)用,這里它沒有被作為造型特殊對待。 如果你的轉(zhuǎn)換函數(shù)沒有被指定支持這種習(xí)慣,那么你的用戶會覺得意外。 由于PostgreSQL允許用不同的參數(shù)類型重載同一個
函數(shù)名,因此存在多個從不同類型到同一目標(biāo)類型的同名轉(zhuǎn)換函數(shù)并不困難。
實際上前一段過于簡化了:有兩種情況中一個函數(shù)調(diào)用結(jié)構(gòu)在沒有被匹配到 一個實際函數(shù)時將被當(dāng)作一次造型請求。如果函數(shù)調(diào)用 name
(x
)沒有正好匹配任何現(xiàn)有函數(shù), 但name
是一種數(shù)據(jù)類型的名稱并且 pg_cast
提供了一種從
x
的類型到這種 類型的二進(jìn)制可強(qiáng)制造型,那么該調(diào)用將被翻譯為一次二進(jìn)制可強(qiáng)制造型。 通過這種例外,二進(jìn)制可強(qiáng)制造型能夠以函數(shù)語法調(diào)用,即便沒有該函數(shù)。 同樣的,如果沒有pg_cast
項,但是該造型是要造型到一種 字符串類型或者是要從一種字符串類型造型,調(diào)用將被翻譯成一次 I/O 轉(zhuǎn)換 造型。這種例外允許以函數(shù)語法調(diào)用 I/O 轉(zhuǎn)換造型。
還有一種例外中的例外:從組合類型到字符串類型的 I/O 轉(zhuǎn)換造型不能使用 函數(shù)語法調(diào)用,而必須被寫成顯式造型語法(CAST
或者 ::
記號)。增加這種例外是因為在引入了自動提供的 I/O 轉(zhuǎn)換 造型之后,在想要引用一個函數(shù)或者列時太容易意外地調(diào)用這種造型。
要使用函數(shù)int4(bigint)
創(chuàng)建一種從類型 bigint
到類型int4
的賦值造型:
CREATE CAST (bigint AS int4) WITH FUNCTION int4(bigint) AS ASSIGNMENT;
(在系統(tǒng)中這種造型已經(jīng)被預(yù)定義)。
CREATE CAST
命令符合 SQL標(biāo)準(zhǔn),不過 SQL 沒有為二進(jìn)制可強(qiáng)制 類型或者實現(xiàn)函數(shù)的額外參數(shù)做好準(zhǔn)備。 AS IMPLICIT
也是一種 PostgreSQL擴(kuò)展。
Copyright©2021 w3cschool編程獅|閩ICP備15016281號-3|閩公網(wǎng)安備35020302033924號
違法和不良信息舉報電話:173-0602-2364|舉報郵箱:jubao@eeedong.com
掃描二維碼
下載編程獅App
編程獅公眾號
聯(lián)系方式:
更多建議: