有没有办法部分初始化 TYPE?

Kat*_*rin 6 postgresql syntax datatypes cast composite-types

我创建了一个自定义类型:

CREATE TYPE my_type as(name text, street text, location text);
Run Code Online (Sandbox Code Playgroud)

初始化这样的类型很容易:

SELECT ROW('a', 'b', 'c')::my_type;
Run Code Online (Sandbox Code Playgroud)

我想知道是否有一种简单的方法可以部分初始化类型,这意味着所有未提及的列都隐式设置为 null。在伪代码中,类似于:

SELECT ROW('a', 'c')::my_type(name, location);
Run Code Online (Sandbox Code Playgroud)

另外,当列未按正确顺序提及时,是否还有一种初始化类型的方法?在伪代码中,类似于:

SELECT ROW('c', 'a', 'b')::my_type(location, name, street);
Run Code Online (Sandbox Code Playgroud)

Erw*_*ter 5

基于您的类型定义的代码示例:

CREATE TYPE my_type AS (name text, street text, location text);
Run Code Online (Sandbox Code Playgroud)

你的语法是不可能的(你已经知道了)。一个普通的铸铁不允许字段的(部分)列表。

SELECT ROW('a', 'c')::my_type(name, location);
Run Code Online (Sandbox Code Playgroud)

普通的 SQL 转换表达式中,您必须为缺失的字段提供 NULL 值(或其他一些默认值):

SELECT ROW('a', NULL, 'c')::my_type;
Run Code Online (Sandbox Code Playgroud)

或者,使用行类型文字作为输入:

SELECT '(a,NULL,c)'::my_type;
Run Code Online (Sandbox Code Playgroud)

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;
Run Code Online (Sandbox Code Playgroud)

未明确填写的字段默认为 NULL。(除非类型具有不同的default,这将是不常见的。)

DELETE显然,不可能总是删除整行。逻辑上的等价物是设置一个子字段NULL

UPDATE tbl
SET    comp.name = NULL
WHERE  tbl_id = 1;
Run Code Online (Sandbox Code Playgroud)

通常,您会在过程语言函数中使用变量 - 默认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
$$
Run Code Online (Sandbox Code Playgroud)

db<>在这里摆弄

不要将 PL/pgSQL 赋值与SELECT INTOSQL 命令SELECT INTO(根本不应该使用,CREATE TABLE AS而是使用)混淆。看:

相关的,更复杂的技巧: