不使用 ARRAY[] 的嵌套复合类型数组的语法

问题描述 投票:0回答:2
CREATE TYPE pencil_count AS(
    pencil_color varchar(30),
    count integer
);

CREATE TYPE pencil_count_with_date(
date_ date,
pencil_count pencil_count[]
);

CREATE TABLE pencils(id serial, pencils_ pencil_count_with_date[]);

INSERT INTO pencils(pencils_) 
VALUES('{"(\"2016-03-13\",{"(\"blue\",1)","(\"red\",2)"})"}');

如果我想在不使用

ARRAY[...]
的情况下添加这个复合数组,正确的语法是什么?

sql arrays postgresql postgresql-9.4
2个回答
1
投票

添加新的嵌套级别时,使用文字字符串的可读性会降低:

CREATE TYPE pencil_count AS(pencil_color varchar(30)
       ,"count" int);

CREATE TYPE pencil_count_with_date AS(date_ date
                                     ,pencil_count pencil_count[]);

CREATE TABLE pencils(id serial, pencils_ pencil_count_with_date[]);

INSERT INTO pencils(pencils_) 
VALUES('{"(
               \"2016-03-13\",
               \"{
                   \"\"(Blue,5)\"\",
                   \"\"(Red,2)\"\"
               }\"
          )"}');   


SELECT pencils_[1].pencil_count[1].pencil_color
FROM pencils;

SqlFiddleDemo

备注:

  1. 您需要根据嵌套级别用
    "
    转义
    \
    来引用每个级别。
  2. 这种模式看起来像是试图将面向对象的世界引入数据库。它可能比标准化版本更难维护并且速度更慢。 相关问题。
  3. 如果需要,您可以使用
    $$
    引用字符串文字。
  4. 使用
    ARRAY
    ROW
    可以更容易地发现每个级别的开始和停止位置。

1
投票

再次询问 Postgres。扩展您之前的问题的程序:

CREATE TEMP TABLE pencil_count (
  pencil_color varchar(30)
, count integer
);

CREATE TABLE pencil_count_with_date (
  date_ date
, pencil_count pencil_count[]
);

CREATE TABLE pencils (
  id serial
, pencils_ pencil_count_with_date[]
);

向 Postgres 询问每个嵌套级别:

INSERT INTO pencil_count VALUES ('red' , 1), ('blue', 2);

SELECT ARRAY(SELECT p FROM pencil_count p)::text AS p_row_arr;

-- with result from above:
INSERT INTO pencil_count_with_date(date_, pencil_count)
VALUES ('2016-04-14', '{"(red,1)","(blue,2)"}')
     , ('2016-04-14', '{"(red,3)","(blue,4)"}');

SELECT ARRAY(SELECT p FROM pencil_count_with_date p)::text AS p2_row_arr;

-- with result from above:
INSERT INTO pencils(pencils_)
VALUES
  ('{"(2016-04-14,\"{\"\"(red,1)\"\",\"\"(blue,2)\"\"}\")"
    ,"(2016-04-15,\"{\"\"(red,3)\"\",\"\"(blue,4)\"\"}\")"}');

SELECT id, pencils_::text FROM pencils;

结果:

id | pencils_
---+-------------------------------------------------------
1  | {"(2016-04-14,\"{\"\"(red,1)\"\",\"\"(blue,2)\"\"}\")"
     ,"(2016-04-15,\"{\"\"(red,3)\"\",\"\"(blue,4)\"\"}\")"}

小提琴
sqlfiddle

我完全同意到目前为止的建议:多层嵌套行类型通常是复杂且低效的。考虑标准化。

我对您上一个问题的回答中有更多内容:

© www.soinside.com 2019 - 2024. All rights reserved.