提问人:Niranjan 提问时间:11/12/2023 最后编辑:marc_sNiranjan 更新时间:11/13/2023 访问量:56
Postgres 将数据插入复合类型 [duplicate]
Postgres insert data into composite type [duplicate]
问:
我在Postgres工作。我有以下复合类型
CREATE TYPE negotiation.diff_type AS
(
operation int,
content text
);
这是我的桌子
CREATE temp TABLE temp_input
(
indication_request_id int,
para_id int,
line_number int,
document_id int,
modified_content text,
created_by text,
diffs diff_type[]
);
在表中,我使用的是 diffs 复合类型。
下面我将数据插入到表中。
INSERT INTO temp_input (myid, para_id, line_number, document_id,modified_content,created_by, diffs)
VALUES (20,2893,10,18,'my content','user1', '{(1,"DDD")"}');
我收到此错误:
错误:格式错误的数组文本:“{(1,”DDD“)”}”
答:
3赞
Mureinik
11/12/2023
#1
您需要用引号将数组的每个元素括起来,然后转义复杂类型文本中的引号:
INSERT INTO temp_input
(indication_request_id, para_id, line_number, document_id,modified_content,created_by, diffs)
VALUES (20,2893,10,18,'my content','user1', '{"(1,\"DDD\")"}');
评论
0赞
Niranjan
11/12/2023
嗨,谢谢你的回答。如果必须将多行插入到差异中,则格式是什么
0赞
Mureinik
11/12/2023
@Niranjan 您的意思是表中的几行还是同一行中的几个差异?
0赞
Niranjan
11/13/2023
同一行中的多个差异
3赞
Jonathan Jacobson
11/12/2023
#2
这就是你如何创建一个包含数组的文字:negotiation.diff_type
array['(1,abc)','(2,def)']::negotiation.diff_type[]
1赞
Erwin Brandstetter
11/13/2023
#3
概念验证
演示命令的正确语法是:
INSERT INTO temp_input (indication_request_id, para_id, line_number, document_id,modified_content,created_by, diffs)
VALUES (20,2893,10,18,'my content','user1', '{"(1,DDD)"}');
具有多个数组元素的多个输入行的正确语法:
INSERT INTO temp_input (indication_request_id, para_id, line_number, document_id,modified_content,created_by, diffs)
VALUES
(2,3,10,18,'my content','user1', '{"(1,DDD)","(2,foo)"}')
, (3,4,10,18,'my content','user1', '{"(1,DDD)","(2,foo)","(3,\"Weird \\\\string\"\"\")"}')
;
只需向 Postgres 询问正确的语法(psql 摘录):
test=> BEGIN;
BEGIN
test=*> CREATE TYPE diff_type AS (
test(*> operation int,
test(*> content text
test(*> );
CREATE TYPE
test=*> CREATE TEMP TABLE syntax_demo OF diff_type;
CREATE TABLE
test=*> INSERT INTO syntax_demo VALUES
test-*> (1, 'DDD')
test-*> , (2, 'foo')
test-*> , (3, 'Weird \string"');
INSERT 0 3
test=*>
test=*> SELECT ARRAY(SELECT t FROM syntax_demo t) AS proper_syntax;
proper_syntax
------------------------------------------------------
{"(1,DDD)","(2,foo)","(3,\"Weird \\\\string\"\"\")"} -- !!!
(1 row)
test=*> ROLLBACK;
测试:
SELECT '{"(1,DDD)","(2,foo)","(3,\"Weird \\\\string\"\"\")"}'::diff_type[];
反向测试:
SELECT (('{"(1,DDD)","(2,foo)","(3,\"Weird \\\\string\"\"\")"}'::diff_type[])[3]).content;
小提琴
(请注意当前有缺陷的显示 dbfiddle.uk:它吞噬了转义的内部级别。\
如您所见,您需要在每行文字(= 复合元素类型)周围括起双引号,但不要在嵌套字符串周围括起来,除非它包含特殊字符。然后你必须摆脱这些,在这一点上,多层嵌套很快就会变得混乱。只需让 Postgres 为您完成即可。
看:
更好的是
不要一开始就去那里。正如 Laurenz 所评论的那样,表定义中的复合数据类型通常表明对正确的数据库设计存在误解。考虑一个半途而废的规范化架构。
评论