Postgresql

有沒有辦法部分初始化 TYPE?

  • September 16, 2018

我創建了一個自定義類型:

CREATE TYPE my_type as(name text, street text, location text);

初始化這種類型很容易:

SELECT ROW('a', 'b', 'c')::my_type;

我想知道是否有一種簡單的方法來部分初始化類型,這意味著所有未提及的列都被隱式設置為 null。在虛擬碼中,類似於:

SELECT ROW('a', 'c')::my_type(name, location);

此外,當列沒有以正確的順序提及時,是否還有一種方法來初始化類型?在虛擬碼中,類似於:

SELECT ROW('c', 'a', 'b')::my_type(location, name, street);

基於您的類型定義的程式碼範例:

CREATE TYPE my_type AS (name text, street text, location text);

你的語法是不可能的(你已經知道了)。普通轉換不允許(部分)欄位列表。

SELECT ROW('a', 'c')::my_type(name, location);

普通的 SQL轉換錶達式中,您必須為缺少的欄位提供 NULL 值(或其他一些預設值):

SELECT ROW('a', NULL, 'c')::my_type;

或者,使用行類型文字作為輸入:

SELECT '(a,NULL,c)'::my_type;

INSERTorUPDATE語句可以單獨針對複合類型的欄位。(底層類型派生自目標。)展示:

CREATE TABLE tbl (tbl_id serial, comp my_type);

INSERT INTO tbl (comp.name, comp.location) VALUES ('a', 'c')

UPDATE tbl
SET    comp.name = 'X'
    , comp.street = 'Y'
WHERE  tbl_id = 1;

未明確填寫的欄位預設為 NULL。(除非該類型具有不同的default,這並不常見。)

顯然不可能DELETE,因為它總是刪除整行。邏輯等價物是設置一個子欄位NULL

UPDATE tbl
SET    comp.name = NULL
WHERE  tbl_id = 1;

通常你會在過程語言函式中使用變數 - 預設PL/pgSQL。你有SELECT INTO。您可以單獨處理複合類型的欄位。展示:

DO
$$
DECLARE
   _var my_type;
BEGIN
  SELECT INTO _var.location, _var.name  -- in any chosen order
         'c', 'a';
  RAISE NOTICE '%', _var;
END
$$

db<>在這裡擺弄

不要將 PL/pgSQL 賦值與SELECT INTOSQL 命令混淆SELECT INTO(根本不應該使用,CREATE TABLE AS而是使用)。看:

相關的,更複雜的技巧:

(展示 hstore#=運算符)

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