Postgres-使用复合类型数组的CRUD操作 [英] Postgres - CRUD operations with arrays of composite types

查看:85
本文介绍了Postgres-使用复合类型数组的CRUD操作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我刚刚发现的Postgres的一个真正整洁的功能是能够定义复合类型的功能-在他们的文档中也称为 ROWS RECORDS 。请考虑以下示例

 创建类型dow_id AS 

tslot smallint,
day smallint
);

现在考虑以下表格

  CREATE SEQUENCE test_id_seq INCREMENT 1 MINVALUE 1 MAXVALUE 2147483647 START 1 CACHE 1; 

创建表test_simple_array

id整数默认DEFAULT nextval(‘test_id_seq’)非空,
dx整数[]
);

创建表test_composite_simple

id整数默认值nextval(‘test_id_seq’)非空,
dx dow_id
);

创建表test_composite_array

id整数默认值nextval(’test_id_seq’)非空,
dx dow_id []
);

前两个表的CRUD操作相对简单。例如,

  INSERT INTO test_simple_array(dx)VALUES('{1,1}'); 
插入到test_composite_simple(dx)值(ROW(1,1));

但是,我不能弄清楚当表中有记录/复合类型数组,如 test_composite_array 所示。我已经尝试过

 插入到test_composite_array(dx)值中(ARRAY(ROW(1,1),ROW(1,2) )); 

由于消息失败


错误: ROW处或附近的语法错误


 插入到test_composite_array(dx)VALUES( {(1,1),(1,2)})); 

由于消息失败


错误:列 {{1,1),(1,2)}不存在


 插入到test_composite_array(dx)VALUES('{(1,1),(1,2) }'); 

这似乎有效,尽管自从随后的
起我感到困惑

从test_composite_array SELECT dx



返回似乎是字符串结果的 {(1,1),(1 ,2)} ,但进一步查询例如

  SELECT id FROM test_composite_array WHERE(dx [1 ])。tslot = 1; 

有效,我也尝试了以下

  SELECT(dx [1])。day FROM test_composite_array; 
UPDATE test_composite_array SET dx [1] .day = 99 WHERE(dx [1] ).tslot = 1;
SELECT(dx [1])。day FROM test_composite_array;

这可同时使用

 更新test_composite_array SET(dx [1])。day = 99 WHERE(dx [1])。tslot = 1; 

失败,我发现我正在弄清楚如何处理记录/复合类型数组在Postgres中,经过反复试验,并且-整个Postgres文档是g从总体上讲非常好-文档中似乎没有对该主题的清晰讨论。任何人都可以向我提出关于如何在Postgres中操作复合类型数组的权威性讨论。



此外,当发生任何意外情况时,

解决方案

您需要带有 ARRAY 的方括号:

  ARRAY [ROW(1,1):: dow_id,ROW(1,2):: dow_id] 

警告:复合类型是一个很棒的功能,但是如果过度使用它们,将会使您的生活更加艰难。您想在 WHERE JOIN 条件中使用复合类型的元素时,您在做错事,你会受苦的标准化关系数据有充分的理由。


One really neat feature of Postgres that I have only just discovered is the ability to define composite type - also referred to in their docs as ROWS and as RECORDS. Consider the following example

CREATE TYPE dow_id AS
(
 tslot smallint,
 day smallint
);

Now consider the following tables

CREATE SEQUENCE test_id_seq INCREMENT 1 MINVALUE 1 MAXVALUE 2147483647 START 1 CACHE 1;

CREATE TABLE test_simple_array 
(
 id integer DEFAULT nextval('test_id_seq') NOT NULL,
 dx  integer []
);

CREATE TABLE test_composite_simple 
(
 id integer DEFAULT nextval('test_id_seq') NOT NULL,
 dx  dow_id
);

CREATE TABLE test_composite_array 
(
 id integer DEFAULT nextval('test_id_seq') NOT NULL,
 dx  dow_id[]
);

CRUD operations on the first two tables are relatively straightforward. For example

INSERT INTO test_simple_array (dx) VALUES ('{1,1}');
INSERT INTO test_composite_simple (dx) VALUES (ROW(1,1));

However, I have not been able to figure out how to perform CRUD ops when the table has an array of records/composite types as in test_composite_array. I have tried

INSERT INTO test_composite_array (dx) VALUES(ARRAY(ROW(1,1),ROW(1,2)));

which fails with the message

ERROR: syntax error at or near "ROW"

and

INSERT INTO test_composite_array (dx) VALUES("{(1,1),(1,2)}");

which fails with the message

ERROR: column "{(1,1),(1,2)}" does not exist

and

INSERT INTO test_composite_array (dx) VALUES('{"(1,1)","(1,2)"}');

which appears to work though it leaves me feeling confused since a subsequent

SELECT dx FROM test_composite_array

returns what appears to be a string result {"(1,1),(1,2)} although a further query such as

SELECT id FROM test_composite_array WHERE (dx[1]).tslot = 1;

works. I also tried the following

SELECT (dx[1]).day FROM test_composite_array;
UPDATE test_composite_array SET dx[1].day = 99 WHERE (dx[1]).tslot = 1;
SELECT (dx[1]).day FROM test_composite_array;

which works while

 UPDATE test_composite_array SET (dx[1]).day = 99 WHERE (dx[1]).tslot = 1;

fails. I find that I am figuring out how to manipulate arrays of records/composite types in Postgres by trial and error and - altough Postgres documentation is generally excellent - there appears to be no clear discussion of this topic in the documentation. I'd be much obliged to anyone who can point me to an authoritative discussion of how to manipulate arrays of composite types in Postgres.

That apart are there any unexpected gotchas when working with such arrays?

解决方案

You need square brackets with ARRAY:

ARRAY[ROW(1,1)::dow_id,ROW(1,2)::dow_id]

A warning: composite types are a great feature, but you will make your life harder if you overuse them. As soon as you want to use elements of a composite type in WHERE or JOIN conditions, you are doing something wrong, and you are going to suffer. There are good reasons for normalizing relational data.

这篇关于Postgres-使用复合类型数组的CRUD操作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆