Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/database/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
PostgreSQL无法将现有列设置为标识_Sql_Database_Postgresql - Fatal编程技术网

PostgreSQL无法将现有列设置为标识

PostgreSQL无法将现有列设置为标识,sql,database,postgresql,Sql,Database,Postgresql,因此,我已经阅读了几十篇帮助材料,似乎博士后经常改变工作方式。我想做的是,将一个现有列设置为IDENTITY,使其成为唯一的主键并自动递增。我在网络上找到了3种解决方案: id integer NOT NULL PRIMARY KEY GENERATED ALWAYS AS IDENTITY id serial NOT NULL PRIMARY KEY SERIAL id bigint NOT NULL DEFAULT nextval(some_seq) 第三个似乎是一个硬编码的解决方案,如果

因此,我已经阅读了几十篇帮助材料,似乎博士后经常改变工作方式。我想做的是,将一个现有列设置为IDENTITY,使其成为唯一的主键并自动递增。我在网络上找到了3种解决方案:

id integer NOT NULL PRIMARY KEY GENERATED ALWAYS AS IDENTITY
id serial NOT NULL PRIMARY KEY SERIAL
id bigint NOT NULL DEFAULT nextval(some_seq)
第三个似乎是一个硬编码的解决方案,如果我有,比如说,500个表,则不太可行,因为我需要针对每个PK的500个序列号,所以我不能这样做

第二种方法已经过时,不再被专家推荐

这就给我留下了第一个解决方案,出于某种原因,我根本无法对我的“现有”表执行此操作。我已经从网上尝试了100种解决方案。以下是我从Stackoverflow尝试的一个来源:

而且。。。令人惊讶的是,同样的方法根本不适用于我。我尝试了以下查询:

ALTER TABLE db.table_name ALTER COLUMN id SET NOT NULL, ALTER id ADD GENERATED AS ALWAYS IDENTITY;
这给了我一个非常模糊的错误,没有任何信息:

ERROR: syntax error at or near ADD
有什么问题吗?我甚至不能用GUI添加这个,它给出了同样的错误。如果有帮助的话,我的服务器正在Linux Ubuntu机器上运行PostgreSQL v9.6.9

所以,我看了几十份帮助材料

但不是,这似乎是真正的官方手册?我不明白为什么这么多人乐于接受互联网上随机陌生人的建议,却忽视了官方手册

好像 博士后经常改变工作方式

AFAIK此自动生成的主键设置已更改一次。二十多年来。如果这个变化率对你来说太大了,那么我强烈建议你避免使用网络编程或移动应用程序

我想说的是 要做的是,将现有列设置为标识,以便它是唯一的主列 关键点和自动增量本身。我总共找到了3种解决方案 在网上:

id integer NOT NULL PRIMARY KEY GENERATED ALWAYS AS IDENTITY
id serial NOT NULL PRIMARY KEY SERIAL
id bigint NOT NULL DEFAULT nextval(some_seq)
第三个似乎是一个硬编码的解决方案,如果我 比如说,有500张表,因为我需要500个序列号 反对每一次PK,所以我不能这样做

这正是第二个解决方案所做的。我不明白为什么有500个序列是你做不到的。假设你已经设法让自己处于一个位置,你有500张桌子,你没有正确设置在第一位

如果有帮助的话,我的服务器正在Linux Ubuntu机器上运行PostgreSQL v9.6.9

的确如此

让我们不要在互联网上随意闲逛,让我们看看实际的postgresql.org手册:

没有提到身份,是吗?难怪它会抱怨你的语法

它在当前文档中,因为他们在版本10中添加了该功能

因此,由于您似乎在没有考虑需求的情况下创建了500个表,因此您面临着自己动手的前景

richardh=> CREATE TABLE t (id integer not null primary key, a text);
CREATE TABLE
richardh=> INSERT INTO t VALUES (1, 'aaa'), (2, 'bbb');
INSERT 0 2
richardh=> CREATE SEQUENCE t_id_seq;
CREATE SEQUENCE
richardh=> ALTER TABLE t ALTER COLUMN id SET DEFAULT nextval('t_id_seq');
ALTER TABLE
richardh=> SELECT setval('t_id_seq', max(id)) FROM t;
 setval 
--------
      2
(1 row)

richardh=> INSERT INTO t VALUES (DEFAULT, 'ccc');
INSERT 0 1
richardh=> SELECT * FROM t ORDER BY id;
 id |  a  
----+-----
  1 | aaa
  2 | bbb
  3 | ccc
(3 rows)
那里——没那么可怕吧

显然,您可以使用plpgsql和一些EXECUTE命令编写脚本,或者使用一些regex grep+transform魔术创建一个外部sql脚本

注意,这里的关键限制是序列没有直接附加到表。如果删除一个表,那么序列将保持不变。一个关键的优势(可能不适用于您的用例)是您可以在多个表之间共享序列号(或者实际上由应用程序直接使用,而根本不存储在表中)

<> P>因为你似乎不喜欢改变,我应该指出,版本9.6将在几年内结束(可能是2022/2023),你可能希望考虑到目前最新版本(2020年7月版本12)的长期稳定性。

< P>只是澄清所说的:

不要使用序列号

对于新应用程序,应改用标识列

您应该什么时候开始?

  • 如果您需要对早于版本10的PostgreSQL的支持
  • 在与表继承的某些组合中(请参见此处)
  • 更一般地说,如果从多个表中使用相同的序列,尽管在这些情况下,显式声明可能比串行类型更可取
您的用例属于第一类。您的Postgres版本早于10.0,因此可以使用
serial
。有一天,当您升级Postgres时,您可以考虑更改为始终作为标识生成的


当需要更改时,此(官方文档中引用的)功能有助于促进更改。

您在哪里找到您尝试的语法?仅供参考,您的第二个语法不正确。它应该是
id serial NOT NULL主键
。而且也不是过时的,只是补充了一种更新的方法。第二种和第三种方法是同一事物的变体。谢谢你的帮助Richard,这确实有帮助。因此,与其直接攻击我的工作方式,对我的实际工作几乎一无所知,不如让我来教育你。我正在将整个生产环境从MSSQL迁移到Postgres,MSSQL有一种不同的自动递增键的方式。再次感谢您,我正在尝试您的解决方案,will brb。@HaiderGhulam如果您要迁移整个生产环境,请自己泡一杯好茶或咖啡,然后坐下来先阅读手册。这四个小时花得很好。这正是我想要确认的,谢谢戈登。