在未指定列的情况下插入记录时获取自动增量字段的错误

时间:2015-10-13 20:25:44

标签: postgresql

我们正在从SQL Server转换为Postgres。我有一个我想要容纳的场景。它涉及将记录从一个表插入到另一个表中,而不列出所有列。我意识到这不是推荐的练习,但是现在让我们把它放在一边。

drop table if exists pk_test_table;

create table public.pk_test_table
(
    recordid SERIAL PRIMARY KEY NOT NULL,
    name text
);

--example 1: works and will insert a record with an id of 1
insert into pk_test_table values(default,'puppies');

--example 2: fails
insert into pk_test_table
select first_name from person_test;

我在第二个例子中收到错误:

  

专栏" recordid"是整数类型但表达式是类型   字符变化提示:你需要重写或强制转换   表达

default关键字将告诉数据库获取下一个值 有没有办法在第二个例子中使用这个关键字?或者某种方式告诉数据库忽略自动递增的列,只是像普通的那样填充它们? 我宁愿使用子查询来获取下一个" id"。
此功能适用于SQL Server,因此存在问题 在此先感谢您的帮助!

3 个答案:

答案 0 :(得分:1)

如果您无法列出列名,则应该使用DEFAULT关键字,就像您在简单插入示例中所做的那样。这不适用于insert into ... select ...

为此,您需要调用nextval。不需要子查询,只需:

insert into pk_test_table
select nextval('pk_test_table_id_seq'), first_name from person_test;

您需要知道序列名称。您可以使用仅将表名作为参数的函数,根据表名从information_schema获取并推断其主键。它很难看,但它起作用。我不认为有任何方法需要知道表名。

答案 1 :(得分:0)

您已将值插入第一列,但您需要在第二个位置添加值。

因此,您可以使用INSERT INTO table(field) VALUES(value)语法。 由于您需要从另一个表中获取值,因此必须删除VALUES并将子查询放在那里。

insert into pk_test_table(name) 
select first_name from person_test;

我希望它有所帮助

答案 2 :(得分:0)

我是通过一个单独的函数这样做的 - 尽管我认为我通过基于每个字段的DEFAULT设置的表级来解决问题。

create table public.pk_test_table
(
    recordid integer NOT NULL DEFAULT nextval('pk_test_table_id_seq'),
    name text,
    field3 integer NOT NULL DEFAULT 64,
    null_field_if_not_set integer,
    CONSTRAINT pk_test_table_pkey PRIMARY KEY ("recordid")
);

有功能:

CREATE OR REPLACE FUNCTION func_pk_test_table() RETURNS void AS
$BODY$
    INSERT INTO pk_test_table (name) 
    SELECT first_name FROM person_test;
$BODY$
LANGUAGE sql VOLATILE;

然后只需通过SELECT FROM func_pk_test_table();

执行该功能

请注意,只要约束允许,就不必指定所有字段。