Синтаксис для массива вложенного составного типа без использования ARRAY[]

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[...]?


person lowdegeneration    schedule 13.03.2016    source источник
comment
пожалуйста, добавьте немного ; к вашим первым двум командам. DDL тоже нуждается в точках с запятой...   -  person wildplasser    schedule 14.03.2016
comment
(1) Почему вы не хотите использовать array[...], это все упрощает. (2) Разве это не то же самое, что ваш другой недавний вопрос?   -  person mu is too short    schedule 14.03.2016
comment
@mu слишком короткий, не совсем, я думаю   -  person lowdegeneration    schedule 14.03.2016


Ответы (2)


Использование литеральной строки будет менее читаемым при добавлении новых вложенных уровней:

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 было бы легче определить, где начинается и где заканчивается каждый уровень.
person Lukasz Szozda    schedule 13.03.2016

Опять же, спросите 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)\"\"}\")"}

SQL Fiddle.

Я полностью согласен с советом: несколько уровней вложенных типов строк обычно сложны и неэффективны. Рассмотрим нормализацию.

Подробнее в моем ответе на ваш предыдущий вопрос:

person Erwin Brandstetter    schedule 14.03.2016
comment
Можно ли использовать массив вложенных композитов для передачи в качестве входных параметров функции postgresFunction и вставки их в нормализованные таблицы? Цените, если есть пример. Пример. Каждое Отправление имеет несколько Товаров отправления и несколько контактных адресов. Мы хотели бы загрузить до 100 отправлений за один вызов функции postgres. - person Maulik Modi; 12.05.2021