复合类型数组的正确语法

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

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

INSERT INTO pencils(pencils_) VALUES('{("blue",5),("red",2)}');

这不起作用并给出错误:

数组文字格式错误。

如果我想在不使用

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

arrays postgresql postgresql-9.4
2个回答
13
投票

到目前为止的建议还不是最佳的。有一个更简单的解决方案和实际适用的解释。
如有疑问,只需让 Postgres 向您展示

CREATE TEMP TABLE pencil_count (  -- table also registers row type
  pencil_color varchar(30)
, count integer
);

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

插入2个基本行:

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

请参阅基本行类型的语法:

SELECT p::text AS p_row FROM pencil_count p;

  p_row
----------
 (red,1)
 (blue,2)

查看行数组的语法:

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

       p_row_arr
------------------------
 {"(red,1)","(blue,2)"}

您所需要做的就是将每个行文字用双引号引起来 - 这仅需要禁用每个行类型中的 comma 的特殊含义。
当没有额外的特殊字符时,额外的(转义的)双引号将是多余的噪音。

这一切与 转义字符串语法没有任何关系,自 Postgres 9.1 以来默认情况下已将其关闭。您必须通过前缀

E
显式声明转义字符串语法,例如
E'string\n'
。但没有充分的理由这样做。

小提琴
sqlfiddle

相关答案及更多解释:


3
投票

我想添加这个复合数组而不使用ARRAY

您可以使用:

INSERT INTO pencils(pencils_) 
VALUES('{"(\"blue\",5)","(\"red\",2)"}');

db<>小提琴演示

行式

请记住,您在 SQL 命令中编写的内容将首先被解释为字符串文字,然后解释为组合。这会使您需要的反斜杠数量加倍(假设使用转义字符串语法)。

字符串文字处理器删除一级反斜杠。

在 SQL 命令中编写复合值时,ROW 构造函数语法通常比复合文字语法更容易使用。在 ROW 中,各个字段值的写入方式与非复合成员时的写入方式相同。

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