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

时间:2012-03-03 03:03:43

标签: 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', '...

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

1 个答案:

答案 0 :(得分:5)

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

缺少enum值的错误消息是:

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

您的错误消息显示存在同名的复合类型,其很可能源自同名的表。您应该避免使用相同的名称

要让公众重现,请考虑以下演示:

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

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

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

如果您必须拥有相同名称的表格和enum,请务必使用架构限定类型名称。在我的例子中:

pg_temp.contacts -- the composite type
public.contacts  -- the enum type