Joh*_*gan 1 ruby mysql 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获得相同的结果.我们通过对数据库的一系列调用找到了一种方法,分别检查每个表.
我只想打电话给数据库.这是我到目前为止所拥有的:
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);
Run Code Online (Sandbox Code Playgroud)
但是,我需要以某种方式将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);
Run Code Online (Sandbox Code Playgroud)
我怎样才能做到这一点?
编辑:在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
Run Code Online (Sandbox Code Playgroud)
你的功能似乎已经很接近了.你想稍微修改它:
TABLE(...)带有类型列的a ,而不是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';
Run Code Online (Sandbox Code Playgroud)
请注意,这currval()不是一个选项,因为它在同一会话中未设置序列时出错(通过调用nextval(),不确定是否有其他方式).