批量更新Postgresql的序列

这篇具有很好参考价值的文章主要介绍了批量更新Postgresql的序列。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

序列(sequence)是 PostgreSQL 中的一种对象,用于生成自动递增的唯一标识符。通常,序列会与表的自增主键一起使用,以确保每个新插入的行都有一个唯一的标识符。在某些情况下,可能需要更新序列的值:

从另一个数据库中导入数据,自增列的值也从原来的数据中导入。导入的过程中,目标数据库的序列不会得到更新,这样如果执行数据库的插入操作,会出现主键冲突的问题。(感觉非常莫名其妙)

如果数据不是很多的情况下,可以通过多次插入,每次都忽略错误,最后序列自增上来了,就可以插入成功了。

本文将介绍如何查询和更新 PostgreSQL 表的序列,并写一个存储过程进行批量操作。

序列与自增主键

在 PostgreSQL 中,序列是由一个名称、一个当前值和递增步长组成的对象。表的自增主键通常依赖于序列来生成唯一的标识符。以下 SQL 语句创建了一个名为 my_table 的表,该表包含一个自增主键列 id

CREATE TABLE my_table (
  id SERIAL PRIMARY KEY,
  name TEXT NOT NULL
);

SERIAL 类型实际上是一个整数类型,并且在表中创建一个名为 my_table_id_seq 的序列对象。每当您向表中插入一行时,PostgreSQL 将自动递增序列并将其值分配给 id 列。

查询表的序列

要查询表的序列,在 PostgreSQL 中,您可以执行以下 SQL 语句:

SELECT pg_get_serial_sequence('my_table', 'id');

这将返回与 my_table 表的 id 列对应的序列名称。请注意,参数的第一个要为标准名称,第二列则需要是纯字符串,对于有大小写的情况,要注意引号的用法:

SELECT pg_get_serial_sequence('"AData"', 'Id');

更新表的序列

要更新表的序列,可以使用setval方法。以下 SQL 语句将将序列 my_table_id_seq 的下一个值设置为 100:

SELECT setval('my_table_id_seq', 100);

我们可以统计当前的最大值,直接将最大值+1赋值给它,对于大小写的情况,也得注意:

SELECT SETVAL('"AData_Id_seq"', (SELECT MAX("Id") + 1 FROM "AData"));

自动化操作

一个个调用还是非常麻烦,我创建了一个函数,可以用来批量更新指定schema内的序列,并利用临时表返回更新的表格与更新的结果。

CREATE OR REPLACE FUNCTION "public"."update_sequence_values"() 
  RETURNS TABLE("var_table_schema" text, "var_table_name" text, "old_max_id" int4, "new_max_id" int4) AS $$
DECLARE
  table_rec RECORD;
  max_id INTEGER;
  old_max_id_val INTEGER;
BEGIN
  -- 创建临时表以保存更新的序列值
	DROP TABLE IF EXISTS temp_sequence_updates;
  CREATE TEMP TABLE temp_sequence_updates (
    var_table_schema TEXT,
    var_table_name TEXT,
    old_max_id INTEGER,
    new_max_id INTEGER
  );

  -- 遍历指定模式下所有包含自增主键的表
  FOR table_rec IN (SELECT DISTINCT(table_schema), table_name, is_identity, column_name FROM information_schema.columns WHERE is_identity= 'YES' AND table_schema = 'public') LOOP
    EXECUTE format('SELECT MAX(%I) FROM %I.%I;', table_rec.column_name, table_rec.table_schema, table_rec.table_name) INTO max_id;

    -- 更新序列
    IF max_id IS NOT NULL THEN
      EXECUTE format('SELECT setval(pg_get_serial_sequence(''%I'', ''%s''), %s, false);', table_rec.table_name, replace(table_rec.column_name, '"','') , max_id + 1);

      -- 记录更新操作的日志信息
      INSERT INTO temp_sequence_updates (var_table_schema, var_table_name, old_max_id, new_max_id) VALUES (table_rec.table_schema, table_rec.table_name , max_id, max_id + 1);
    END IF;
  END LOOP;

  -- 返回更新操作的日志信息
  RETURN QUERY SELECT * FROM temp_sequence_updates;
END;
$$ LANGUAGE plpgsql;
	
SELECT * FROM update_sequence_values();

注意:

  1. 格式化字符%s%I有不同,在 PostgreSQL 中,%I 是格式化字符串中的一个占位符,用于在 SQL 查询中引用标识符(如列名、表名等)。它类似于 %s 占位符,但是会将参数中的标识符转换为带有双引号的字符串,以防止 SQL 注入攻击。对于setval参数,需要灵活选择使用%s与%I
  2. 函数使用is_identity()来判断是否为自增的列。

注意事项

在更新表的序列时,请注意以下几点:文章来源地址https://www.toymoban.com/news/detail-423677.html

  • 序列是全局对象,因此在更新前,请确保没有其他用户当前正在使用该序列。
  • 一定多检查,不要更新错误的序列。
  • 操作之前先备份数据。

到了这里,关于批量更新Postgresql的序列的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【PostgreSQL】导出数据库表(或序列)的结构和数据

    要导出 PostgreSQL 数据库的结构和数据,你可以使用 pg_dump 命令行工具。 pg_dump 可以生成一个 SQL 脚本文件,其中包含了数据库的结构(表、索引、视图等)以及数据。下面是如何使用 pg_dump 导出数据库结构和数据的示例: 导出数据库结构和数据: 使用以下命令来导出整个数据

    2024年02月11日
    浏览(30)
  • [pgrx开发postgresql数据库扩展]6.返回序列的函数编写(1)单值序列

    上篇文章是中规中矩的标准计算函数,就算不用pgrx,也是可以正常理解的,所以基本上没有什么对于pgrx框架有关系的东西(唯一有关系的东西,应该就是Rust的时间类型与pgrx的时间类型的计算了)。 这篇文章会讲一个pgrx对于postgresql或者说对于任何数据库扩展来说都比较有用

    2024年02月03日
    浏览(31)
  • 探索PostgreSQL的新功能:最新版本更新解析

    PostgreSQL作为一种强大而开源的关系型数据库管理系统,不断在不断进化和改进。每一次的版本更新都带来了更多功能和改进,让用户在处理大规模数据和复杂查询时体验更好的性能和功能。在本文中,我们将深入探索PostgreSQL的最新版本更新,了解新增的功能和改进,以及这

    2024年02月14日
    浏览(32)
  • Postgresql关于JSON、JSONB的操作符、处理函数(持续更新)

    (只列举本次用到的函数,其他函数在文章后面有详解) SELECT answer_id,  jsonb_array_elements(option_ids)::INTEGER  AS option_id FROM db_live_answer  WHERE survey_code=\\\'No.20230605165428002\\\'      如果所有json数组都包含两个新列的两个元素,那么使用固定路径,如dmfay的答案。 否则,你应该使用jso

    2024年02月08日
    浏览(32)
  • 【postgresql 基础入门】插入数据的多种方式 单条,多值,查询结果,插入数据冲突处理,批量导入,多种方式让数据插入更灵活

    ​ 专栏内容 : postgresql内核源码分析 手写数据库toadb 并发编程 ​ 开源贡献 : toadb开源库 个人主页 :我的主页 管理社区 :开源数据库 座右铭:天行健,君子以自强不息;地势坤,君子以厚德载物. 入门准备 postgrersql基础架构 快速使用 初始化集群 数据库服务管理 psql客户

    2024年02月08日
    浏览(41)
  • postgresql 内核源码分析 事务提交回滚状态记录 clog机制流程,commit log文件格式,事务状态为什么单独记录的原因,分组优化及leader更新机制

    ​ 专栏内容 : postgresql内核源码分析 手写数据库toadb 并发编程 ​ 开源贡献 : toadb开源库 个人主页 :我的主页 管理社区 :开源数据库 座右铭:天行健,君子以自强不息;地势坤,君子以厚德载物. PostgreSQL是一种开源的关系型数据库管理系统,其内核源码的分析对于深入理

    2024年02月08日
    浏览(46)
  • 数据库(Oracle)序列(Sequence)的基本使用

    在Oracle中可以用SEQUENCE生成自增字段。Sequence序列是Oracle中用于生成数字序列的对象,可以创建一个唯一的数字作为主键。 你可能有疑问为什么要使用序列? 不能使用一个存储主键的表并每次递增吗?或者将列设置为AUTO INCREMENT? 如果使用一个表来储存主键值的话,也许需要

    2024年02月05日
    浏览(42)
  • SQL server中字段自增:IDENTITY、序列Sequence

    1.列字段自增`IDENTITY 在 SQL Server 中, IDENTITY(1, 1) 是用于定义一个自增长列的属性。它的含义如下: IDENTITY :表示该列是一个自增长列。 (1, 1) :表示自增长列的起始值为 1,每次递增 1。 当你在创建表时使用 IDENTITY(1, 1) 属性,就会为该表创建一个自增长列,每次插入新记录时

    2024年02月05日
    浏览(41)
  • UE4 Sequence添加基础动画效果 (03-主序列的使用)

    在上一篇的基础上添加一些摄像头的跟拍效果 1.鼠标右键新建 Animation-》关卡序列    命名为主序列 2.双击打开主序列 3.点击 窗口-》内容浏览器-》内容浏览器2 找到入口序列  4.将入口序列拖入主序列中  5.让时间轴总长保持与入口序列长度一致  6.双击时间轴来进入入口序

    2024年02月06日
    浏览(34)
  • 使用序列(Sequence)在 Oracle 数据库中管理唯一标识符

    目录 1. 创建序列 2. 使用序列生成唯一值 3. 序列的常见应用场景 结论 简介: 在 Oracle 数据库中,序列(Sequence)是一种强大的工具,用于生成唯一的数值标识符。序列提供了一种简单而高效的方式来管理表的主键或其他需要唯一值的列。本文将介绍 Oracle 中序列的用法,包括

    2024年02月05日
    浏览(36)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包