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)
基于您的类型定义的代码示例:
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)
INSERT
orUPDATE
语句可以单独针对复合类型的字段。(底层类型派生自目标。)演示:
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 INTO
SQL 命令SELECT INTO
(根本不应该使用,CREATE TABLE AS
而是使用)混淆。看:
相关的,更复杂的技巧:
#=
运算符)