mysql - 获取 PostgreSQL 中所有序列的最大 ID

标签 mysql ruby postgresql auto-increment

我们在我们的数据库上有一个监视器来检查接近 max-int 或 max-bigint 的 ID。我们刚从 MySQL 迁移过来,我正在努力在 PostgreSQL 上进行类似的检查。我希望有人能提供帮助。

这是MySQL中的查询

SELECT table_name, auto_increment FROM information_schema.tables WHERE table_schema = DATABASE();

我正在尝试从 PostgreSQL 获得相同的结果。我们找到了一种通过大量调用数据库来实现这一点的方法,分别检查每个表。

我只想对数据库进行 1 次调用。这是我到目前为止所拥有的:

CREATE OR REPLACE FUNCTION getAllSeqId() RETURNS SETOF record AS
$body$
DECLARE
  sequence_name varchar(255);
BEGIN
  FOR sequence_name in SELECT relname FROM pg_class WHERE (relkind = 'S')
  LOOP
      RETURN QUERY EXECUTE 'SELECT last_value FROM ' || sequence_name;
  END LOOP;
  RETURN;
END
$body$
LANGUAGE 'plpgsql';
SELECT last_value from getAllSeqId() as(last_value bigint);

但是,我需要以某种方式将 sequence_name 添加到每条记录,以便在 [table_name, last_value] 或 [sequence_name, last_value] 的记录中获得输出。

所以我想这样调用我的函数:

 SELECT sequence_name, last_value from getAllSeqId() as(sequence_name varchar(255), last_value bigint);

我该怎么做?

编辑:在 ruby​​ 中,这会创建我们正在寻找的输出。如您所见,我们执行 1 次调用以获取所有索引,然后为每个索引执行 1 次调用以获取最后一个值。一定是更好的方法。

def perform
  find_auto_inc_tables.each do |auto_inc_table|
    check_limit(auto_inc_table, find_curr_auto_inc_id(auto_inc_table))
  end 
end 

def find_curr_auto_inc_id(table_name)
  ActiveRecord::Base.connection.execute("SELECT last_value FROM #{table_name}").first["last_value"].to_i
end 

def find_auto_inc_tables
  ActiveRecord::Base.connection.execute(
    "SELECT c.relname " +
    "FROM pg_class c " +                                                       
    "WHERE c.relkind = 'S'").map { |i| i["relname"] }
end 

最佳答案

您的功能似乎已经很接近了。您需要将其稍微修改为:

  • 将序列名称作为文字包含
  • 返回带有类型化列的 TABLE(...) 而不是 SET OF RECORD 因为调用者更容易

修改后的版本:

CREATE OR REPLACE FUNCTION getAllSeqId() RETURNS TABLE(seqname text,val bigint) AS
$body$
DECLARE
  sequence_name varchar(255);
BEGIN
  FOR sequence_name in SELECT relname FROM pg_class WHERE (relkind = 'S')
  LOOP
      RETURN QUERY EXECUTE  'SELECT ' || quote_literal(sequence_name) || '::text,last_value FROM ' || quote_ident(sequence_name);
  END LOOP;
  RETURN;
END
$body$
LANGUAGE 'plpgsql';

请注意 currval() 不是一个选项,因为当序列未在同一 session 中设置时它会出错(通过调用 nextval(),不确定如果有任何其他方式)。

关于mysql - 获取 PostgreSQL 中所有序列的最大 ID,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16819315/

相关文章:

java - SWF 最大工作流程执行时间限制

ruby - 我可以使用 "**"glob 遍历 Ruby 中的符号链接(symbolic link)目录吗?

php - Yii:STAT 与条件的关系

python - 允许用户搜索项目的最佳方式是什么

mysql - 检索和插入日期时间时 MYSQL 的默认行为是什么?遇到一个有趣的时区偏移问题

ruby-on-rails - Rails 不记录请求

database - 如何将表从一个数据库自动迁移到不同服务器上的其他数据库?

postgresql - 在没有 Postgis 功能的情况下转储或恢复 Postgresql 数据库

postgresql - 使用PostgreSQL驱动程序进行静态编译Qt时出错

MySQL sleep 模式错误