<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                合規國際互聯網加速 OSASE為企業客戶提供高速穩定SD-WAN國際加速解決方案。 廣告
                # CREATE TYPE ## Name CREATE TYPE?--?定義一個新數據類型 ## Synopsis ``` CREATE TYPE _name_ AS ( [ _attribute_name_ _data_type_ [ COLLATE _collation_ ] [, ... ] ] ) CREATE TYPE _name_ AS ENUM ( [ '_label_' [, ... ] ] ) CREATE TYPE _name_ AS RANGE ( SUBTYPE = _subtype_ [ , SUBTYPE_OPCLASS = _subtype_operator_class_ ] [ , COLLATION = _collation_ ] [ , CANONICAL = _canonical_function_ ] [ , SUBTYPE_DIFF = _subtype_diff_function_ ] ) CREATE TYPE _name_ ( INPUT = _input_function_, OUTPUT = _output_function_ [ , RECEIVE = _receive_function_ ] [ , SEND = _send_function_ ] [ , TYPMOD_IN = _type_modifier_input_function_ ] [ , TYPMOD_OUT = _type_modifier_output_function_ ] [ , ANALYZE = _analyze_function_ ] [ , INTERNALLENGTH = { _internallength_ | VARIABLE } ] [ , PASSEDBYVALUE ] [ , ALIGNMENT = _alignment_ ] [ , STORAGE = _storage_ ] [ , LIKE = _like_type_ ] [ , CATEGORY = _category_ ] [ , PREFERRED = _preferred_ ] [ , DEFAULT = _default_ ] [ , ELEMENT = _element_ ] [ , DELIMITER = _delimiter_ ] [ , COLLATABLE = _collatable_ ] ) CREATE TYPE _name_ ``` ## 描述 `CREATE TYPE`為當前數據庫注冊一個新的數據類型。 定義該類型的用戶成為其所有者。 如果給出模式名,那么該類型是在指定模式中創建。否則它將在當前模式中創建。 類型名必需和同一模式中任何現有的類型或者域不同。(因為表和數據類型有聯系, 所以類型名也不能和同模式中的表名字沖突。) 有5種形式的`CREATE TYPE`,顯示在上面的語法摘要里。 他們分別創建_復合類型_、_枚舉類型_、 _范圍類型_、_基本類型_或_殼類型_。 前四個在下面依次討論。殼類型是簡單的一個稍后定義的類型的占位符; 通過發出沒有參數只有類型名的`CREATE TYPE`創建。 當創建范圍類型和基本類型時,殼類型作為向前引用需要,在下面章節中討論。 ### 復合類型 `CREATE TYPE`的第一種形式創建一個復合類型。 復合類型是通過一列屬性名和數據類型聲明的。如果它的數據類型可排序, 那么也可以指定屬性的排序。復合類型本質上和一個表的行類型一樣, 但是如果只是想定義一個類型,那么使用`CREATE TYPE` 就可以避免直接創建實際的表。一個獨立的復合類型是有用的,例如, 做為一個函數的參數或者返回類型。 要想能夠創建一個復合類型,必須在所有的屬性類型上有`USAGE`權限。 ### 枚舉類型 `CREATE TYPE`的第二種形式創建一個枚舉(enum)類型, 在[Section 8.7](#calibre_link-825)中描述。枚舉類型接受一個或更多的引用標簽的列表, 每個標簽必須小于`NAMEDATALEN`字節長度 (在標準的PostgreSQL建立中是64字節)。 ### 范圍類型 `CREATE TYPE`的第三種形式創建一個新的范圍類型, 在[Section 8.17](#calibre_link-1153)中描述。 范圍類型的`_subtype_` 可以是有一個相關的b-tree操作符類(決定范圍類型值的順序)的任意類型。 通常子類型的缺省b-tree操作符類用于決定順序;要使用一個非缺省的操作符類, 用`_subtype_opclass_`指定它的名字。 如果子類型是可排序的,并且你希望在范圍的排序中使用非缺省的排序, 那么使用`_collation_` 選項指定想要的排序。 可選的`_canonical_` 函數必須接受一個被定義的范圍類型的參數,并且返回相同類型的值。 適用時,這用于轉換范圍類型到標準形式。參閱[Section 8.17.8](#calibre_link-2083) 獲取更多信息。創建一個`_canonical_` 函數比較棘手,因為它必須在范圍類型可以被聲明之前定義。要做到這點, 必須先創建一個殼類型,殼類型是一個除了名字和所有者之外沒有其他屬性的占位符類型。 這可以通過發出沒有其他額外參數的`CREATE TYPE` `_name_`命令來完成。 然后可以使用該殼類型作為參數和結果聲明該函數,最后可以使用相同的名字聲明范圍類型。 這將自動使用有效的范圍類型替代殼類型條目。 可選的`_subtype_diff_`函數必須接受兩個 `_subtype_`類型的值作為參數, 并且返回`雙精度`值表示兩個給定值之間的不同。 雖然這是可選的,但是提供它允許GiST索引在范圍類型字段上有更大的效率。 參閱[Section 8.17.8](#calibre_link-2083)獲取更多信息。 ### 基本類型 `CREATE TYPE`的第四種形式創建一個新的基本類型(標量類型)。 要創建一個新的基本類型,你必須是一個超級用戶。 (做這個限制是因為一個錯誤的類型定義會混淆或者甚至崩潰服務器。) 參數可以按任意順序出現,而不是上面顯示的那樣,并且大多數都是可選的。 必須在定義類型之前先用`CREATE FUNCTION`注冊兩個或更多個函數。 支持函數`_input_function_` 和`_output_function_`是必須的, 而函數`_receive_function_`、 `_send_function_`、 `_type_modifier_input_function_`、 `_type_modifier_output_function_` 和`_analyze_function_`是可選的。 通常,這些函數必須用 C 或者其它低層語言編寫。 `_input_function_` 函數將該類型的外部文本形式轉換成可以被該類型的操作符和函數識別的內部形式。 `_output_function_`用途相反。 輸入函數可以聲明為接受一個類型為`cstring`的參數, 或者接受三個類型分別為`cstring`、`oid`、 `integer`的參數。第一個參數是 C 字符串形式的輸入文本, 第二個參數是該類型自身的 OID(數組類型除外,這種情況下它們接受自身元素的類型 OID), 第三個是目標字段的`typmod`(如果未知則傳遞 -1)。 輸入函數必須返回一個自身數據類型的值。通常,輸入函數應當被聲明為 STRICT , 否則當讀取 NULL 輸入時將被使用第一個參數為 NULL 進行調用, 并且必須仍然返回 NULL 或報錯。(這個特性主要是為了支持域輸入函數, 這種函數可能需要拒絕 NULL 輸入。)輸出函數必須被聲明為接受一個新數據類型的參數, 并且必須返回`cstring`類型。輸出函數不會被使用 NULL 調用。 可選的`_receive_function_` 把該類型的外部二進制表現形式轉換成內部表現形式。如果沒有提供這個函數, 那么該類型不能用二進制輸入。二進制格式應該選取那種比較容易轉換同時 還有一定移植性的內部格式。比如,標準的整數數據類型使用網絡字節序作為 外部的二進制表現形式,而內部表現形式則是機器的本機字節序。例如, 接收函數應該聲明為接受一個類型為`internal`的參數, 或者是三個類型分別為`internal`、`oid`、 `integer`的參數。第一個參數是一個指向一個`StringInfo` 緩沖區的、保存接受字節串的指針;可選的參數和文本輸入函數一樣。 接收函數必須返回一個該類型的數據值。通常接收函數應當被聲明為 STRICT , 否則否則當讀取 NULL 輸入時將被使用第一個參數為 NULL 進行調用, 并且必須仍然返回 NULL 或報錯。這個特性主要是為了支持域接收函數, 這種函數可能需要拒絕 NULL 輸入。同樣,可選的 `_send_function_` 把類型的內部表現形式轉換為外部二進制表現形式。如果沒有提供這些函數, 那么類型就不能用二進制方式輸出。 發送函數必須聲明為接收一個新數據類型并且必須返回`bytea`結果。 發送函數不會被以 NULL 值調用。 這個時候你應該覺得奇怪,輸入和輸出函數怎么可以聲明為返回新類型的結果或者是接受新類型的參數, 而且是在新類型創建之前就需要創建它們。答案是類型必須被首先定義為一個_殼類型_, 它只是一個除了名稱和屬主之外沒有其他屬性的占位符類型。這可以通過沒有其他額外參數的 `CREATE TYPE` `_name_`命令來完成。 然后就可以引用該殼類型定義輸入輸出函數。最后,`CREATE TYPE` 把這個殼類型替換成完整的、有效的類型定義,這樣就可以使用新類型了。 如果支持類型修飾符,那么可選的 `_type_modifier_input_function_` 和`_type_modifier_output_function_` 是需要的,這是附屬于類型聲明的可選的約束,如`char(5)`和 `numeric(30,2)`。PostgreSQL 允許用戶定義的類型接受一個或多個簡單的約束或標識符作為修飾符。不過, 這個信息必須能夠裝進一個非負的整型值里,以在系統表中存儲。 `_type_modifier_input_function_` 以`cstring`數組的形式傳送聲明的修飾符。它必須檢查值的有效性 (如果值是錯誤的則拋出一個錯誤),如果是正確的,則返回一個非負的 `integer`值,該值將被作為字段"typmod"存儲。如果類型沒有 `_type_modifier_input_function_`, 那么類型修飾符將被拒絕。`_type_modifier_output_function_` 轉換內部的整數typmod值為用戶顯示的正確形式。它必須返回一個`cstring` 值,該值是附加到類型名之后的準確的字符串;如`numeric`的函數返回`(30,2)`。 允許省略`_type_modifier_output_function_`, 省略的情況下,缺省顯示形式是只有存儲的typmod整型值包含在圓括號中。 可選的`_analyze_function_` 為該數據類型的字段執行與該類型相關的統計信息收集。缺省時, 如果該類型有個缺省的 B-tree 操作符類,那么`ANALYZE` 將嘗試使用該類型的"等于"和"小于"操作符收集信息。 對于非標量類型,這種行為很可能不合適,因此可以通過提供一個自定義的分析函數覆蓋它。 分析函數必須聲明為接收單獨一個`internal`類型的參數, 并且返回一個`boolean`結果。分析函數的詳細 API 在 `src/include/commands/vacuum.h`里。 盡管新類型的內部表現形式只有輸入輸出函數和其它你創建來使用該類型的函數了解, 但內部表現形式還是有幾個屬性必須為PostgreSQL聲明。 `_internallength_`是最重要的一個。 基本數據類型可定義成為定長,這時`_internallength_` 是一個正整數,也可以是變長的,通過把`_internallength_` 設為`VARIABLE`表示。(在內部,這個狀態是通過將`typlen` 設置為-1 實現的。)所有變長類型的內部形式都必須以一個四字節整數開頭, 這個整數給出此類型這個數值的全長。 可選的標記`PASSEDBYVALUE`表明該類型的數值是按值而不是引用傳遞。 你不能傳遞那些內部形式大于`Datum`類型尺寸(大多數機器上是 4 字節, 有些是 8 字節)的數據類型的值。 `_alignment_`參數聲明該數據類型要求的對齊存儲方式。 允許的數值等效于按照 1, 2, 4, 8 字節邊界對齊。請注意變長類型必須有至少 4 字節的對齊, 因為它們必須包含一個`int4`作為第一個部分。 `_storage_` 參數允許為變長數據類型選擇存儲策略(定長類型只允許使用`plain`)。 `plain`聲明該數據類型總是用內聯的方式而不是壓縮的方式存儲。 `extended`聲明系統將首先試圖壓縮一個長的數據值, 然后如果它仍然太長的話就將它的值移出主表,但系統將不會壓縮它。 `external`聲明禁止系統進行壓縮并且允許將它的值移出主表。 `main`允許壓縮,但是不贊成把數值移動出主表(如果實在不能放在一行里的話, 仍將移動出主表,它比`extended`和`external`項更愿意保存在主表里)。 `_like_type_` 參數為指定數據類型的基本代表屬性提供一個可選的方式:從某些現有的類型中拷貝他們。 `_internallength_`、 `_passedbyvalue_`、 `_alignment_`和 `_storage_`的值從命名的類型中拷貝。 (這是可能的,盡管通常不需要,通過和`LIKE`子句一起指定他們, 來覆蓋一些這些值。)這種方式指定代表,在新類型"piggybacks" 的低級實現以某種方式在現有類型上時尤其有用。 `_category_`和 `_preferred_` 參數可以用于幫助控制哪個隱式轉換將被用于模糊的情況。 每個數據類型都屬于一個由單個ASCII字符命名的類,并且每個類型不是"preferred" 就是不在它的類中。當這個規則對于解析重載函數或操作符有幫助時, 解析器更愿意轉換為優先的類型(但是只限于來自不在相同類中的其他類型)。 更多信息請參閱[Chapter 10](#calibre_link-447)。對于沒有隱式轉換到或來自任意其他類型的類型, 保留這些設置作為缺省就足夠了。不過,對于有隱式轉換的的相關類型的組, 通常標記他們都屬于一個類并且在該類中選取一個或兩個"最一般" 的類型作為優先是有幫助的。當添加一個用戶定義的類型到一個現有的內建類時, `_category_`參數尤其有用, 如數值型或字符串類型。但是,也有可能創建新的完全用戶定義的類型類別。 選取任意ASCII字符而不是一個大寫的字母來命名這樣一個類別。 如果用戶希望字段的數據類型缺省時不是 NULL ,那么可以在`DEFAULT` 關鍵字里聲明一個缺省值(可以被附著在特定字段上的`DEFAULT`子句覆蓋)。 用`ELEMENT`關鍵字聲明數組元素的類型。 比如,`ELEMENT = int4`定義了一個 4 字節整數 (`int4`)的數組。有關數組類型的更多細節在下面描述。 可用`_delimiter_` 指定用于這種類型數組的外部形式的數值之間的分隔符。 缺省的分隔符是逗號(`,`)。 請注意分隔符是和數組元素類型相關聯,而不是數組類型本身。 如果可選的布爾參數`_collatable_`為真, 那么該類型的字段定義和表達式可以通過使用`COLLATE` 子句攜帶排序信息。取決于在該類型上函數操作符的實現,以實際上利用排序信息; 僅僅通過標記該類型可排序,這就不會自動發生。 ### 數組類型 在創建用戶定義類型的時候,PostgreSQL 自動創建一個與之關聯的數組類型,其名字由該元素類型的名字前綴一個下劃線組成, 并且如果有必要保持它小于`NAMEDATALEN`字節長度時截斷。 (如果這樣生成的名字與一個現有的類型名沖突,那么重復該進程, 知道找到一個不沖突的名字。)這個隱含創建的數組類型是變長并且使用內建的 `array_in`和`array_out`輸入和輸出函數。 數組類型追蹤它的元素類型的所有者或模式的任意更改, 并且如果元素類型有更改時刪除。 你很可能會問如果系統自動制作正確的數組類型,那為什么還要有個`ELEMENT`選項? 使用`ELEMENT`的場合有一:你定義的定長類型碰巧在內部是一個一定數目相同事物的數組, 而你又想允許這 N 個事物可以通過下標直接訪問,除了某些操作符將把該類型當做整體進行處理。 比如,類型`point`表示為兩個浮點數,每個可以用`point[0]` 和`point[1]`訪問。請注意這個功能只適用于定長類型, 并且其內部形式是一個相同定長域的序列。一個可以下標化的變長類型必須有被 `array_in`和`array_out`使用的一般化的內部表現形式。 出于歷史原因(也就是,這是明顯錯誤的,但是要改變它卻太晚了), 定長數組類型的下標從 0 開始,而不是像變長數組那樣的從 1 開始。 ## 參數 `_name_` 將要創建的類型名(可以有模式修飾) `_attribute_name_` 復合類型的一個屬性(字段)的名字 `_data_type_` 要成為一個復合類型的字段的現有數據類型的名字 `_collation_` 與復合類型或范圍類型字段有關的現有排序的名字 `_label_` 表示與枚舉類型的值有關的文本標簽的字符串字面值 `_subtype_` 元素類型的名字,范圍類型將代表的范圍 `_subtype_operator_class_` 該子類型的b-tree操作符類的名字 `_canonical_function_` 范圍類型的標準化函數的名字 `_subtype_diff_function_` 子類型的差異函數的名字 `_input_function_` 一個函數的名稱,將數據從外部文本形式轉換成內部格式。 `_output_function_` 一個函數的名稱,將數據從內部格式轉換成適于顯示的外部文本形式。 `_receive_function_` 一個函數的名稱,把數據從類型的外部二進制形式轉換成內部形式 `_send_function_` 一個函數的名稱,把數據從類型的內部形式轉換成外部二進制形式 `_type_modifier_input_function_` 一個函數的名稱,把修飾符的數組類型轉換成內部形式 `_type_modifier_output_function_` 一個函數的名稱,把類型的修飾符的內部形式轉換成外部形式 `_analyze_function_` 為該數據類型執行統計分析的函數名 `_internallength_` 一個數值常量,說明新類型的內部表現形式的字節長度。缺省假定它是變長的。 `_alignment_` 該數據類型的存儲對齊要求。如果聲明了,必須是`char`、 `int2`、`int4`(缺省)、`double`之一。 `_storage_` 該數據類型的存儲策略。如果聲明了,必須是`plain`(缺省)、 `external`、`extended`、`main`之一。 `_like_type_` 與新類型將要有的表現相同的現有數據類型的名字。 `_internallength_`、 `_passedbyvalue_`、 `_alignment_`、 `_storage_`的值是從該類型中拷貝的, 除非在`CREATE TYPE`命令中明確的說明覆寫。 `_category_` 這個類型的類別代碼(單個ASCII字符)。"用戶定義類型"卻省是`'U'`。 其他標準類別代碼可以在[Table 47-52](#calibre_link-1465)中找到。 你也可以選擇其他ASCII字符來創建自定義類別。 `_preferred_` 如果這個類型在它的類型類別中是首選類型則為真,否則為假。缺省是假。 在一個現有的類型類別中創建一個新的首選類型時要非常小心, 因為這會導致行為上意外的變化。 `_default_` 該類型的缺省值。若省略則為 NULL `_element_` 被創建的類型是數組;這個聲明數組元素的類型。 `_delimiter_` 數組元素之間分隔符 `_collatable_` 如果這個類型的操作可以使用排序信息則為真。缺省為假。 ## 注意 因為一旦類型被創建之后對它的使用就沒有限制, 所以創建一個基本類型或范圍類型就等價于授予所有用戶執行類型定義中指定的各個函數的權限, 這對于大多數類型定義中指定的函數來說不會造成什么不良問題。 但是如果你設計的新類型在內部形式和外部形式之間轉換的時候使用"敏感信息", 那么你仍然要再三考慮、多加小心。 PostgreSQL版本8.3之前, 生成的數組類型的名字總是正好是元素類型的名字前置一個下劃線字符(`_`)。 (因此限制類型名字的長度比其他名字的字符要少。)雖然這仍然是通常的情況, 但是數組類型名字可能會有變化,假使最大長度名字或與下劃線開始的用戶類型名字沖突。 依賴于這個約定的書寫代碼因此棄用了。取而代之,使用`pg_type`.`typarray` 來定位與一個給定類型相關的數組類型。 避免使用以下劃線開始的類型和表名是明智的。雖然服務器將改變生成的數組類型名, 以避免與用戶給定的名字沖突,但是仍然有混淆的更顯, 尤其是老的客戶端軟件可能假設以下劃線開始的類型名總是代表數組。 PostgreSQL版本8.2之前,殼類型創建語法 `CREATE TYPE` `_name_`并不存在。 創建新的基本類型之前必須首先創建其輸入函數。這樣,PostgreSQL 將會首先把新類型的名字看作輸入函數的返回類型并隱含創建殼類型, 然后這個殼類型將被隨后定義的輸入輸出函數引用。這種老式的方法目前仍然被支持, 但已經反對使用,將來可能不再支持。同樣,為了避免函數定義中的臨時殼類型偶然地搞亂系統表, 當輸入函數用 C 語言書寫時,將只能用這種方法創建殼類型。 在PostgreSQL 7.3 以前,要通過使用占位偽類型 `opaque`代替函數的前向引用來避免創建殼類型。7.3 之前`cstring` 參數和結果同樣需要聲明為`opaque`。要支持加載舊的轉儲文件, `CREATE TYPE`將接受那些用`opaque`聲明的輸入輸出函數, 但是它將發出一條通知并且用正確的類型改變函數的聲明。 ## 例子 這個例子創建一個復合類型并且在一個函數定義中使用它: ``` CREATE TYPE compfoo AS (f1 int, f2 text); CREATE FUNCTION getfoo() RETURNS SETOF compfoo AS $$ SELECT fooid, fooname FROM foo $$ LANGUAGE SQL; ``` 這個命令創建枚舉類型,并且將它用于一個表定義: ``` CREATE TYPE bug_status AS ENUM ('new', 'open', 'closed'); CREATE TABLE bug ( id serial, description text, status bug_status ); ``` 這個例子創建一個范圍類型: ``` CREATE TYPE float8_range AS RANGE (subtype = float8, subtype_diff = float8mi); ``` 這個命令創建`box`基本數據類型,并且將這種類型用于一個表定義: ``` CREATE TYPE box; CREATE FUNCTION my_box_in_function(cstring) RETURNS box AS ... ; CREATE FUNCTION my_box_out_function(box) RETURNS cstring AS ... ; CREATE TYPE box ( INTERNALLENGTH = 16, INPUT = my_box_in_function, OUTPUT = my_box_out_function ); CREATE TABLE myboxes ( id integer, description box ); ``` 如果`box`的內部結構是一個四個`float4`的數組,可以使用: ``` CREATE TYPE box ( INTERNALLENGTH = 16, INPUT = my_box_in_function, OUTPUT = my_box_out_function, ELEMENT = float4 ); ``` 來允許一個 box 的數值成分成員可以用下標訪問。否則該類型和前面的行為一樣。 這條命令創建一個大對象類型并將其用于一個表定義: ``` CREATE TYPE bigobj ( INPUT = lo_filein, OUTPUT = lo_fileout, INTERNALLENGTH = VARIABLE ); CREATE TABLE big_objs ( id integer, obj bigobj ); ``` 更多的例子,包括合適的輸入和輸出函數,位于[Section 35.11](#calibre_link-837)。 ## 兼容性 `CREATE TYPE`命令的第一種形式,創建一個復合類型, 符合SQL標準。其他形式是PostgreSQL 的擴展。SQL標準中的`CREATE TYPE` 語句也定義了沒有在PostgreSQL中實現的其他形式。 用0屬性創建一個復合類型的能力是PostgreSQL 與標準具體的偏差(類似于`CREATE TABLE`中的相同情況)。 ## 又見 [ALTER TYPE](#calibre_link-649), [CREATE DOMAIN](#calibre_link-567), [CREATE FUNCTION](#calibre_link-4), [DROP TYPE](#calibre_link-647)
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看