【问题标题】:Reset auto increment counter in postgres在 postgres 中重置自动增量计数器
【发布时间】:2011-07-17 13:54:12
【问题描述】:

我想强制表格的自动递增字段为某个值,我尝试了这个:

ALTER TABLE product AUTO_INCREMENT = 1453

ALTER SEQUENCE product  RESTART WITH 1453;
ERROR:  relation "your_sequence_name" does not exist

我是 postgres 的新手 :(

我有一张表 productIdname 字段

【问题讨论】:

  • 如果是新的,为什么不使用 pgAdmin 并检查它将生成的命令?
  • 通常表被命名为“产品”而不是“产品”。在这种情况下,您的序列将被命名为“products_id_seq”。请确保您正在寻找正确的序列。跨度>

标签: sql postgresql reset auto-increment


【解决方案1】:

如果您使用id 列创建了表product,那么序列就不会简单地称为product,而是称为product_id_seq(即${table}_${column}_seq)。

这是您需要的ALTER SEQUENCE 命令:

ALTER SEQUENCE product_id_seq RESTART WITH 1453

您可以使用 psql 中的\ds 命令查看数据库中的序列。如果您执行\d product 并查看列的默认约束,nextval(...) 调用也会指定序列名称。

【讨论】:

  • 从这条消息中不清楚正确的语法是什么。它是:ALTER SEQUENCE product_id_seq RESTART WITH 1453;
  • 只是因为我对上面的解析很差,这是我重申完全相同的事情的方式。语法是ALTER SEQUENCE yourTableName_yourColumnName_seq RESTART WITH #,其中“seq”是文字文本,您输入一个数字作为#。不要忽略下划线。 :-)
  • 请注意,如果不使用公共架构,则需要以 my_schema 作为前缀。 ALTER SEQUENCE my_schema.product_id_seq RESTART WITH 1453
  • 请注意,您重新启动时使用的值是您要使用的 next 值。所以如果你已经有一个id为1453的记录,你应该RESTART WITH 1454
  • 带有IDENTITY 列约束,你可以使用ALTER TABLE tbl ALTER COLUMN id RESTART SET START 1453
【解决方案2】:

设置序列计数器:

setval('product_id_seq', 1453);

如果您不知道序列名称,请使用pg_get_serial_sequence 函数:

select pg_get_serial_sequence('product', 'id');
 pg_get_serial_sequence 
------------------------
 public.product_id_seq

参数为表名和列名。

或者只是在psql 提示符处发出\d product

=> \d product
                         Table "public.product"
 Column |  Type   |                      Modifiers                       
--------+---------+------------------------------------------------------
 id     | integer | not null default nextval('product_id_seq'::regclass)
 name   | text    | 

【讨论】:

  • SELECT setval('product_id_seq', 1453);为我工作
  • 我正在尝试选择 pg_get_serial_sequence('Domain.products', 'id');但抱怨架构不存在。如何运行此查询?我是 psql 新手。
【解决方案3】:

这是您要查找的命令,假设您的产品表序列是 product_id_seq:

ALTER SEQUENCE product_id_seq RESTART WITH 1453;

【讨论】:

    【解决方案4】:

    以下命令会自动为您执行此操作:这也会删除表中的所有数据。所以要小心。

    TRUNCATE TABLE someTable RESTART IDENTITY;
    

    【讨论】:

    • 当心 - 这也会删除您的所有数据
    • @Loolooii,只是标记它;如果不熟悉 SQL 的人在这里搜索,因为他们手动向具有自动增量字段的表中添加了一行(例如,通过 ORM),那么这个解决方案可能不是他们所期望的。
    • TABLE 关键字是多余的。 TRUNCATE someTable RESTART IDENTITY; 就够了。
    • @ihossain 你试过TRUNCATE someTable RESTART IDENTITY CASCADE; 吗?
    • 对于引用的表,你可以做TRUNCATE table2, table1 RESTART IDENTITY;
    【解决方案5】:

    为了方便访问者,从评论转换

    从这条消息中不清楚正确的语法是什么。它是:

    ALTER SEQUENCE product_id_seq RESTART WITH 1453;
    

    【讨论】:

      【解决方案6】:

      要重置自动增量,您必须使用以下查询获取序列名称。

      语法:

      SELECT pg_get_serial_sequence(‘tablename’, ‘ columnname‘);
      

      例子:

      SELECT pg_get_serial_sequence('demo', 'autoid');
      

      查询将返回autoid的序列名称为“Demo_autoid_seq” 然后使用以下查询重置 autoid

      语法:

      ALTER SEQUENCE sequenceName RESTART WITH value;
      

      例子:

      ALTER SEQUENCE "Demo_autoid_seq" RESTART WITH 1453;
      

      【讨论】:

        【解决方案7】:

        如果您想重置从 GUI 自动递增,请按照以下步骤操作。

        1. 转到您的数据库
        2. 点击公开
        3. 在表格列表页面中,您可以看到 TABS 之类的“表格”、“视图”、“序列”。
        4. 点击序列
        5. 当您点击“Sequences”时,您可以看到所有序列表,点击任何您想要重置
        6. 之后您可以看到多项选择,例如“Alter”、“Set Value”、“Restart”、“Reset”等...
        7. 然后点击重置,然后添加一个新行。

        【讨论】:

          【解决方案8】:

          如果您有一个包含 IDENTITY 列的表,您想要重置下一个值,可以使用以下命令:

          ALTER TABLE <table name> 
              ALTER COLUMN <column name> 
                  RESTART WITH <new value to restart with>;
          

          【讨论】:

          • 一个 + 用于在没有 sequence 的情况下使用,或者您不能截断表格。我认为这是最好的答案
          【解决方案9】:
          -- Change the starting value of the sequence
          
          ALTER SEQUENCE project_id_seq RESTART 3000;
          

          相同但动态:

          SELECT SETVAL('project_id_seq', (SELECT MAX(id) + 1 FROM project));
          

          我同意SELECT 的使用令人不安,但它有效。

          来源: https://kylewbanks.com/blog/Adding-or-Modifying-a-PostgreSQL-Sequence-Auto-Increment

          【讨论】:

          • 如果我没记错的话,PG用last_value和is_call来表示它们的序列,从(1, false)开始,然后是(1, true), (2, true)...所以MAX (id) + 1 应该是 MAX(id) 而不是跳过一个 id。
          • 我还必须重新启动我的 postgres 实例才能使其正常工作。 brew services restart postgresql
          • SELECT SETVAL('project_id_seq', (SELECT MAX(id) + 1 FROM project));完美运行但是有没有办法将增量值重置为 0。所以新条目以 0 索引开头?
          【解决方案10】:

          要获取序列ID,请使用

          SELECT pg_get_serial_sequence('tableName', 'ColumnName');
          

          这会给你 sequesce id 作为 tableName_ColumnName_seq

          要获取最后一个种子编号,请使用

          select currval(pg_get_serial_sequence('tableName', 'ColumnName'));
          

          或者如果您知道序列 id 已经直接使用它。

          select currval(tableName_ColumnName_seq);
          

          它会给你最后的种子编号

          重置种子数使用

          ALTER SEQUENCE tableName_ColumnName_seq RESTART WITH 45
          

          【讨论】:

            【解决方案11】:

            请注意,如果您的表名带有'_',它会在序列名中被删除。

            例如表名:user_tokens 列:id 序列名称:usertokens_id_seq

            【讨论】:

            • 对我来说不是这样。我有同样的条件,但下划线保留在序列名称的名称中
            【解决方案12】:

            使用此查询检查什么是 Sequence Key 与 Schema 和 Table,

            SELECT pg_get_serial_sequence('"SchemaName"."TableName"', 'KeyColumnName'); // output: "SequenceKey"
            

            使用此查询将增量值一一增加,

            SELECT nextval('"SchemaName"."SequenceKey"'::regclass); // output 110
            

            当插入到表中时,下一个递增的值将用作键 (111)。

            使用此查询将特定值设置为增量值

            SELECT setval('"SchemaName"."SequenceKey"', 120);
            

            当插入到表中时,下一个递增值将用作键 (121)。

            【讨论】:

            • 感谢您指出如何获取不同模式的 seqName :)
            【解决方案13】:

            节点脚本:修复所有表标识:自动增量/nextval,基于上次插入它。

            const pg = require('pg');
            const { Client } = pg;
            
            const updateTables = async () => {
            
              const client = new Client({
                user: 'postgres',
                host: 'localhost',
                database: 'my-database',
                password: 'postgres',
                port: 5432,
              });
            
              await client.connect();
            
              console.log('Connected');
            
              const execQuery = async (queryStr, params = []) => {
                return new Promise((resolve, reject) => {
                  client.query(queryStr, params, (error, results) => {
                    if (error) {
                      reject(error);
                    } else {
                      resolve(results);
                    }
                  })
                })
              }
            
              const tablesRes = await execQuery(`
                SELECT table_name
                FROM information_schema.tables
                WHERE table_type='BASE TABLE'
                AND table_schema='public';
              `)
            
              const tables = tablesRes.rows.map(row => row.table_name);
            
              tables.map(async tableName => {
                let lastId;
                try {
                  const res = await execQuery(`SELECT id from "${tableName}" ORDER BY id DESC LIMIT 1`);
                  lastId = res.rows[0].id;
                } catch (e) {}
            
                if (lastId) {
                  const nextId = lastId + 1;
                  const queryStr = `ALTER SEQUENCE ${tableName}_id_seq RESTART WITH ${nextId}`;
                  await execQuery(queryStr);
                  console.log(tableName, queryStr);
                }
              })
            
            };
            
            updateTables();
            

            【讨论】:

              【解决方案14】:

              要将其设置为您可以使用的下一个最高值:

              SELECT SETVAL(pg_get_serial_sequence('table_name', 'column_name'), (SELECT MAX(column_name) FROM table_name));
              

              【讨论】:

              • 最有用的答案。谢谢!
              【解决方案15】:

              2021 年,Postgres 11.12

              ALTER SEQUENCE 对我不起作用,它以某种方式将其重置为 null。 对我有用的是:

              SELECT setval('<table>_<column>_seq', 5);
              

              【讨论】:

              • Postgres 12.8 也适用于我,谢谢
              【解决方案16】:

              如果表是这样的

              bigint NOT NULL GENERATED ALWAYS AS IDENTITY ( INCREMENT 1 START 0)
              

              插入0-9范围内的一些记录后,会导致下一个insert发生冲突,所以要重置START:

              ALTER TABLE ... ALTER COLUMN ... RESTART WITH 10;
              

              【讨论】:

                【解决方案17】:

                我不确定以上所有答案, 如果我没有序列名称怎么办? 如果我不想截断表格怎么办?

                以下查询帮助我在不影响现有数据的情况下做到这一点。

                ALTER TABLE <<table_name>>
                    ALTER COLUMN <<primary_key_column_name>> RESTART SET START 4044;
                

                【讨论】:

                  猜你喜欢
                  • 2017-04-30
                  • 1970-01-01
                  • 1970-01-01
                  • 2012-04-21
                  • 1970-01-01
                  • 2017-01-02
                  • 2021-08-25
                  • 1970-01-01
                  • 2015-02-13
                  相关资源
                  最近更新 更多