共計(jì) 2951 個(gè)字符,預(yù)計(jì)需要花費(fèi) 8 分鐘才能閱讀完成。
本篇內(nèi)容介紹了“PostgreSQL 的數(shù)據(jù)類型轉(zhuǎn)換規(guī)則是什么”的有關(guān)知識(shí),在實(shí)際案例的操作過程中,不少人都會(huì)遇到這樣的困境,接下來就讓丸趣 TV 小編帶領(lǐng)大家學(xué)習(xí)一下如何處理這些情況吧!希望大家仔細(xì)閱讀,能夠?qū)W有所成!
一、Value Storage
插入到數(shù)據(jù)表的值按如下步驟轉(zhuǎn)換為目標(biāo)列數(shù)據(jù)類型.
Value Storage Type Conversion
1. 檢查是否與目標(biāo)完全匹配
2. 如不能完全匹配, 則轉(zhuǎn)換表達(dá)式為目標(biāo)類型. 如果在 pg_cast 系統(tǒng)目錄中存在兩種類型的轉(zhuǎn)換信息, 那么這是可以做到的. 否則, 如果表達(dá)式為 unknown 類型,literal string 的內(nèi)容會(huì)反饋給輸入轉(zhuǎn)換例程, 用于轉(zhuǎn)換為目標(biāo)類型.
3. 檢查目標(biāo)類型是否有 sizing 轉(zhuǎn)換.sizing cast 是從該類型到自身的一種轉(zhuǎn)換. 如在 pg_cast 找到相應(yīng)的 cast, 在存儲(chǔ)到目標(biāo)列前在該表達(dá)式上應(yīng)用該轉(zhuǎn)換. 實(shí)現(xiàn)函數(shù)通常需要一個(gè)額外類為 integer 的參數(shù), 用于接收目標(biāo)列的 atttypmod 屬性值 (該值通常用于表示長(zhǎng)度), 同時(shí)需要第 3 個(gè)類型為 boolean 的參數(shù)用于確定 cast 是顯式還是隱式轉(zhuǎn)換. 轉(zhuǎn)換函數(shù)有責(zé)任執(zhí)行所有與長(zhǎng)度相關(guān)的語義如大小檢查或截?cái)?
下面是一些例子:
character 字符類型轉(zhuǎn)換
testdb=# CREATE TABLE vv (v character(20));
CREATE TABLE
testdb=# INSERT INTO vv SELECT abc || def
INSERT 0 1
testdb=# SELECT v, octet_length(v) FROM vv;
v | octet_length
----------------------+--------------
abcdef | 20
(1 row)
‘a(chǎn)bc’和’def’這兩者類型被視為 unknown, 轉(zhuǎn)換為 text 類型執(zhí)行連接操作,|| 操作的結(jié)果為 text, 該結(jié)果轉(zhuǎn)換為 bpchar(blank-padded char,character 的內(nèi)部名稱) 用以匹配目標(biāo)列類型.
查看 pg_cast 系統(tǒng)目錄
testdb=# select oid,typname from pg_type where typname in ( text , bpchar , char
oid | typname
------+---------
18 | char
25 | text
1042 | bpchar
(3 rows)
testdb=# select * from pg_cast where castsource=25;
oid | castsource | casttarget | castfunc | castcontext | castmethod
-------+------------+------------+----------+-------------+------------
11381 | 25 | 2205 | 1079 | i | f
11397 | 25 | 1042 | 0 | i | b
11398 | 25 | 1043 | 0 | i | b
11409 | 25 | 18 | 944 | a | f
11412 | 25 | 19 | 407 | i | f
11466 | 25 | 142 | 2896 | e | f
(6 rows)
轉(zhuǎn)換函數(shù)
testdb=# select oid,proname,prorettype,proargtypes,prosrc from pg_proc where oid in (0,407,944,1079,2896);
oid | proname | prorettype | proargtypes | prosrc
------+----------+------------+-------------+---------------
407 | name | 19 | 25 | text_name
944 | char | 18 | 25 | text_char
1079 | regclass | 2205 | 25 | text_regclass
2896 | xml | 142 | 25 | texttoxml
(4 rows)
二、UNION, CASE, and related constructs
UNION(INTERSECT/EXCEPT) 必須匹配可能的不太相同的類型以成形成一個(gè)單獨(dú)的結(jié)果集. 該解析算法分別應(yīng)用于 union 查詢的每一個(gè)輸出列.CASE, ARRAY, VALUES, GREATEST 和 LEAST 使用相同的算法匹配表達(dá)式并選擇結(jié)果數(shù)據(jù)類型.
Type Resolution for UNION, CASE, and Related Constructs
1. 如果所有輸入是同一種類型, 而且不是 unknown, 則解析為該類型
2. 如果所有輸入為同一個(gè) domain 類型, 則后續(xù)步驟的處理的時(shí)候把類型視為 domain 的基類型
3. 如果所有輸入類型為 unknown, 則解析為 text(字符串的首選類型). 否則,unknown 類型的輸入接下來會(huì)被忽略
4. 如果非 unknown 類型不是同一個(gè)類型, 則失敗
5. 選擇第一個(gè)非 unknown 類型的首選類型
6. 否則, 選擇允許所有優(yōu)先非 unknown 輸入可被隱私轉(zhuǎn)換的最后一個(gè)非 unknown 輸入類型
7. 轉(zhuǎn)換所有輸入為選擇的類型, 如存在不能轉(zhuǎn)換的類型, 則失敗
下面是一些例子:
Simple Union
testdb=# SELECT 1.2 AS numeric UNION SELECT 1;
numeric
---------
1
1.2
(2 rows)
1.2 明確為 numeric 類型,integer 1 可隱式轉(zhuǎn)換為 numeric, 因此使用 numeric 類型
Transposed Union
testdb=# SELECT 1 AS real UNION SELECT CAST(2.2 AS REAL);
real
------
1
2.2
(2 rows)
實(shí)數(shù)不能隱式轉(zhuǎn)換為整數(shù), 但整數(shù)可隱式轉(zhuǎn)換為 real, 因此 1 會(huì)被轉(zhuǎn)換為 real,union 結(jié)果類型為 real.
Nested Union
testdb=# SELECT NULL UNION SELECT NULL UNION SELECT 1;
psql: ERROR: UNION types text and integer cannot be matched
LINE 1: SELECT NULL UNION SELECT NULL UNION SELECT 1;
PG 會(huì)把多個(gè) Unions 視為成對(duì)的操作, 該 SQL 可被視為”(SELECT NULL UNION SELECT NULL) UNION SELECT 1”. 按照上面的規(guī)則, 內(nèi)部 union 會(huì)解析為 text 類型, 外部 union 的輸入為 text 和 integer 類型, 導(dǎo)致上述錯(cuò)誤.
“PostgreSQL 的數(shù)據(jù)類型轉(zhuǎn)換規(guī)則是什么”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識(shí)可以關(guān)注丸趣 TV 網(wǎng)站,丸趣 TV 小編將為大家輸出更多高質(zhì)量的實(shí)用文章!