由于"格式错误的记录文字"无法插入记录

pun*_*ish 5 postgresql types visibility

以下问题让我难过

SELECT string_agg(e.enumlabel, '|') as enum_value
FROM pg_type t 
   JOIN pg_enum e on t.oid = e.enumtypid  
   JOIN pg_catalog.pg_namespace n ON n.oid = t.typnamespace 
WHERE typname = 'contacts'

above|below|lateral|lateral-bottom|lateral-top|within

CREATE TABLE unit_contacts
(
  id integer NOT NULL DEFAULT nextval('unit_contacts_id_seq1'::regclass),
  unit_id integer NOT NULL,
  old_contact contacts NOT NULL,
  contact contacts NOT NULL,
  old_with_unit integer NOT NULL,
  with_unit integer NOT NULL,
  CONSTRAINT unit_contacts__pkey PRIMARY KEY (id )
)
WITH (
  OIDS=FALSE
);

mm=> INSERT INTO unit_contacts VALUES (15, 1, 'below', 'below', 8112, 2);
ERROR:  malformed record literal: "below"
LINE 1: ...SERT INTO unit_contacts VALUES (15, 1, 'below', '...
Run Code Online (Sandbox Code Playgroud)

我无法弄清楚为什么我根本无法插入行.

Erw*_*ter 5

显然,你正在陷入命名冲突.

缺失enum值的错误消息是:

ERROR:  invalid input value for enum rainbow: "below"
LINE 1: INSERT INTO t VALUES (1, 'below');
Run Code Online (Sandbox Code Playgroud)

您的错误消息显示存在同名的复合类型,这很可能源于同名.你应该避免使用相同的名字!

为了让大众重现,请考虑以下演示:

CREATE TYPE contacts  AS ENUM ('above', 'below', 'lateral');
SELECT 'above'::contacts;  -- all good, before the next step

CREATE TEMP TABLE contacts (id int, x text); -- !the crucial part

SELECT string_agg(e.enumlabel, '|') as enum_value
FROM   pg_type t 
JOIN   pg_enum e on t.oid = e.enumtypid  
WHERE  t.typname = 'contacts'; -- all good

CREATE TEMP TABLE t (id int, r contacts);
INSERT INTO t VALUES (1, 'above');  -- ERROR
SELECT 'above'::contacts;  -- same ERROR
Run Code Online (Sandbox Code Playgroud)

只有当enumtype和table(行类型)存在于两个不同的模式中时,才会发生这种情况.PostgreSQL不允许在同一模式中使用它们.在您的情况下,当您创建表时,具有表的模式(复合类型)的模式显然enum位于search_path中 类型的模式之前.或许当时甚至不存在这种类型.看到:enum

在我的示例中,临时表首先出现,因为pg_temp默认情况下架构首先出现在搜索路径中.当我创建表时,contacts被解析为行类型(pg_temp.contacts),而不是enum类型(public.contacts).

如果必须有一个表和一个enum同名的表,请确保对正在使用的类型名称进行模式限定.在我的例子中:

pg_temp.contacts -- the composite type
public.contacts  -- the enum type
Run Code Online (Sandbox Code Playgroud)