批量更新Postgresql的序列

来源:https://www.cnblogs.com/podolski/archive/2023/04/24/17349217.html
-Advertisement-
Play Games

序列(sequence)是 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()來判斷是否為自增的列。

註意事項

在更新表的序列時,請註意以下幾點:

  • 序列是全局對象,因此在更新前,請確保沒有其他用戶當前正在使用該序列。
  • 一定多檢查,不要更新錯誤的序列。
  • 操作之前先備份數據。
除非特殊說明,本作品由podolski創作,採用知識共用署名 4.0 國際許可協議進行許可。歡迎轉載,轉載請保留原文鏈接~喜歡的觀眾老爺們可以點下關註或者推薦~
您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 記錄 mongo 資料庫用原生自帶的命令工具使用 json 文件方式進行導入、導出的操作! 在一次數據更新中,同事把老數據進行了清空操作,但是新的邏輯數據由於某種原因(好像是她的電腦中病毒了),一直無法正常連接資料庫進行數據插入,然後下午2點左右要給甲方演示,所以要緊急恢複本地的部分數據到生產庫。 ...
  • 功能03-優惠券秒殺01 4.功能03-優惠券秒殺 4.1全局唯一ID 4.1.1全局ID生成器 每個店鋪都可以發佈優惠券: 當用戶搶購時,就會生成訂單,並保存到tb_voucher_order這張表中。訂單表如果使用資料庫的自增id就存在一些問題: id的規律性太明顯:用戶可以根據id猜測一些信息 ...
  • 這裡介紹一下如何在Zabbix 6下麵,使用預設自帶的模板MSSQL by ODBC來監控SQL Server資料庫。官方關於Template DB MSSQL By ODBC的介紹如下鏈接所示: https://www.zabbix.com/integrations/mssql 這個項目對應的gi ...
  • 1、通過慢查日誌等定位那些執行效率較低的SQL語句 2、explain 分析SQL的執行計劃 需要重點關註type、rows、filtered、extra。 type由上至下,效率越來越高 ALL 全表掃描 index 索引全掃描 range 索引範圍掃描,常用語<,<=,>=,between,in ...
  • 4月22日,2023首屆雲資料庫技術沙龍 MySQL x ClickHouse 專場,在杭州市海智中心成功舉辦。本次沙龍由玖章算術、菜根發展、良倉太炎共創聯合主辦。圍繞“技術進化,讓數據更智能”為主題,匯聚位元組跳動、阿裡雲、玖章算術、華為雲、騰訊雲、百度的6位資料庫領域專家,深入 MySQL x C... ...
  • 摘要:“銀行業數字化轉型實踐交流會”杭州站順利收官。 由華為與北京先進數通聯合主辦的“銀行業數字化轉型實踐交流會”杭州站順利收官,會議邀請了金融科技先鋒企業、機構和多位資深專家,一起深入交流銀行業數字化轉型業務場景的探索和實踐。其中,華為雲資料庫專家在現場分享了華為雲GaussDB的前沿技術和項目實 ...
  • 實驗一、Flume 組件安裝配置 1、下載和解壓 Flume 可 以 從 官 網 下 載 Flume 組 件 安 裝 包 , 下 載 地 址 如 下 URL 鏈 接 所 示 https://archive.apache.org/dist/flume/1.6.0/ [root@master ~]# l ...
  • 實時同步是 ChunJun 的⼀個重要特性,指在數據同步過程中,數據源與⽬標系統之間的數據傳輸和更新⼏乎在同⼀時間進⾏。 在實時同步場景中我們更加關註源端,當源系統中的數據發⽣變化時,這些變化會⽴即傳輸並應⽤到⽬標系統,以保證兩個系統中的數據保持⼀致。這個特性需要作業運⾏過程中 source 插件不 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...