当postgres的主键序列不同步时,如何重置?
我遇到了我的主键序列与我的表行不同步的问题。
也就是说,当我插入新行时,我得到一个重复的键错误,因为串行数据类型中隐含的序列返回了一个已经存在的数字。
这似乎是由于导入/还原未正确维护序列引起的。
#1楼
放在一起
CREATE OR REPLACE FUNCTION "reset_sequence" (tablename text)
RETURNS "pg_catalog"."void" AS
$body$
DECLARE
BEGINEXECUTE 'SELECT setval( pg_get_serial_sequence(''' || tablename || ''', ''id''),(SELECT COALESCE(MAX(id)+1,1) FROM ' || tablename || '), false)';
END;
$body$ LANGUAGE 'plpgsql';
将修复给定表的“ id'
序列(例如,通常对于django是必需的)。
#2楼
重置所有序列,除了每个表的主键均为“ id”外,无需假名:
CREATE OR REPLACE FUNCTION "reset_sequence" (tablename text, columnname text)
RETURNS "pg_catalog"."void" AS
$body$
DECLARE
BEGINEXECUTE 'SELECT setval( pg_get_serial_sequence(''' || tablename || ''', ''' || columnname || '''),(SELECT COALESCE(MAX(id)+1,1) FROM ' || tablename || '), false)';
END;
$body$ LANGUAGE 'plpgsql';select table_name || '_' || column_name || '_seq', reset_sequence(table_name, column_name) from information_schema.columns where column_default like 'nextval%';
#3楼
丑陋的黑客使用一些外壳魔术来解决它,这不是一个很好的解决方案,但可能会激发其他有类似问题的人:)
pg_dump -s <DATABASE> | grep 'CREATE TABLE' | awk '{print "SELECT setval(#" $3 "_id_seq#, (SELECT MAX(id) FROM " $3 "));"}' | sed "s/#/'/g" | psql <DATABASE> -f -
#4楼
最快捷的方法:
SELECT setval('tbl_tbl_id_seq', max(tbl_id)) FROM tbl;
tbl_id
是表tbl
的serial
列,从序列tbl_tbl_id_seq
(这是默认的自动名称) tbl_tbl_id_seq
。
如果您不知道附加序列的名称(不一定是默认格式),请使用pg_get_serial_sequence()
:
SELECT setval(pg_get_serial_sequence('tbl', 'tbl_id'), max(tbl_id)) FROM tbl;
这里没有一一对应的错误。 每个文档:
两参数形式将序列的
last_value
字段设置为指定值,并将其is_called
字段设置为true,这意味着下一个nextval
将在返回值之前使序列前进 。
大胆强调我的。
如果表可以为空, 并且在这种情况下实际上从1开始:
SELECT setval(pg_get_serial_sequence('tbl', 'tbl_id'), COALESCE(max(tbl_id) + 1, 1), false)
FROM tbl;
我们不能只使用2参数形式并以0
开头,因为默认情况下序列的下限是1 (除非自定义)。
并发
尚无防范并发序列活动或上述查询中写入表的措施。 如果相关,您可以将表锁定为独占模式。 当您尝试同步时,它可以防止并发事务写入更多的数字。 (它还会临时阻止无害的写入,而不会干扰最大数量。)
但这并没有考虑到客户端可能已经预先获取了序列号而在主表上没有任何锁的情况(这可能会发生)。 为此,也只增加序列的当前值,而不要减少它。 看起来可能有些偏执,但这与序列的性质以及防止并发问题保持一致。
BEGIN;LOCK TABLE tbl IN EXCLUSIVE MODE;SELECT setval('tbl_tbl_id_seq', max(tbl_id))
FROM tbl
HAVING max(tbl_id) > (SELECT last_value FROM tbl_tbl_id_seq);COMMIT;
#5楼
如果在加载用于初始化的自定义SQL数据时看到此错误,则另一种避免这种情况的方法是:
而不是写:
INSERT INTO book (id, name, price) VALUES (1 , 'Alchemist' , 10),
从初始数据中删除id
(主键)
INSERT INTO book (name, price) VALUES ('Alchemist' , 10),
这样可以使Postgres序列保持同步!
#6楼
尝试重新索引 。
更新:如评论中所指出,这是对原始问题的答复。
#7楼
-- Login to psql and run the following-- What is the result?
SELECT MAX(id) FROM your_table;-- Then run...
-- This should be higher than the last result.
SELECT nextval('your_table_id_seq');-- If it's not higher... run this set the sequence last to your highest id.
-- (wise to run a quick pg_dump first...)BEGIN;
-- protect against concurrent inserts while you update the counter
LOCK TABLE your_table IN EXCLUSIVE MODE;
-- Update the sequence
SELECT setval('your_table_id_seq', COALESCE((SELECT MAX(id)+1 FROM your_table), 1), false);
COMMIT;
来源-Ruby论坛
#8楼
该命令仅用于更改PostgreSQL中自动生成的键序列值
ALTER SEQUENCE "your_sequence_name" RESTART WITH 0;
代替零,您可以输入要从其重新启动序列的任何数字。
默认序列名称将为"TableName_FieldName_seq"
。 例如,如果您的表名是"MyTable"
而字段名是"MyID"
,那么您的序列名将是"MyTable_MyID_seq"
。
这个答案与@murugesanponappan的答案相同,但是他的解决方案中存在语法错误。 您不能在alter
命令中使用子查询(select max()...)
。 因此,您要么必须使用固定的数值,要么需要使用变量来代替子查询。
#9楼
这里有一些非常难解的答案,我假设它在被问到的时候曾经是很糟糕的,因为这里的很多答案都不适用于9.3版。 从8.0版开始的文档就提供了以下问题的答案:
SELECT setval('serial', max(id)) FROM distributors;
另外,如果您需要注意区分大小写的序列名称,可以采用以下方法:
SELECT setval('"Serial"', max(id)) FROM distributors;
#10楼
SELECT setval...
使JDBC陷入僵局,因此这是Java兼容的方法:
-- work around JDBC 'A result was returned when none was expected.'
-- fix broken nextval due to poorly written 20140320100000_CreateAdminUserRoleTables.sql
DO 'BEGIN PERFORM setval(pg_get_serial_sequence(''admin_user_role_groups'', ''id''), 1 + COALESCE(MAX(id), 0), FALSE) FROM admin_user_role_groups; END;';
#11楼
重新检查公共模式功能中的所有序列
CREATE OR REPLACE FUNCTION public.recheck_sequence (
)
RETURNS void AS
$body$
DECLARE_table_name VARCHAR;_column_name VARCHAR; _sequence_name VARCHAR;
BEGINFOR _table_name IN SELECT tablename FROM pg_catalog.pg_tables WHERE schemaname = 'public' LOOPFOR _column_name IN SELECT column_name FROM information_schema.columns WHERE table_name = _table_name LOOPSELECT pg_get_serial_sequence(_table_name, _column_name) INTO _sequence_name;IF _sequence_name IS NOT NULL THEN EXECUTE 'SELECT setval('''||_sequence_name||''', COALESCE((SELECT MAX('||quote_ident(_column_name)||')+1 FROM '||quote_ident(_table_name)||'), 1), FALSE);';END IF;END LOOP; END LOOP;
END;
$body$
LANGUAGE 'plpgsql'
VOLATILE
CALLED ON NULL INPUT
SECURITY INVOKER
COST 100;
#12楼
ALTER SEQUENCE sequence_name重新启动(从table_name中选择max(id)max); 不起作用
从@tardate复制答案:
SELECT setval(pg_get_serial_sequence('table_name', 'id'), MAX(id)) FROM table_name;
#13楼
pg_get_serial_sequence
可以用来避免对序列名称的任何错误假设。 这会在一连拍中重置序列:
SELECT pg_catalog.setval(pg_get_serial_sequence('table_name', 'id'), (SELECT MAX(id) FROM table_name)+1);
或更简而言之:
SELECT pg_catalog.setval(pg_get_serial_sequence('table_name', 'id'), MAX(id)) FROM table_name;
但是,这种形式不能正确处理空表,因为max(id)为null,也不能设置setval 0,因为它将超出序列范围。 一种解决方法是诉诸ALTER SEQUENCE
语法,即
ALTER SEQUENCE table_name_id_seq RESTART WITH 1;
ALTER SEQUENCE table_name_id_seq RESTART; -- 8.4 or higher
但是ALTER SEQUENCE
的用途有限,因为序列名称和重新启动值不能为表达式。
似乎最好的通用解决方案是使用false作为第三个参数调用setval
,从而允许我们指定“要使用的下一个值”:
SELECT setval(pg_get_serial_sequence('t1', 'id'), coalesce(max(id),0) + 1, false) FROM t1;
这打勾了我所有的框:
- 避免对实际序列名称进行硬编码
- 正确处理空表
- 处理具有现有数据的表,并且不会在序列中留下空洞
最后,请注意pg_get_serial_sequence
仅在该序列归列所有时才起作用。 如果将递增列定义为serial
类型,则将是这种情况,但是,如果手动添加了序列,则必须确保还执行ALTER SEQUENCE .. OWNED BY
。
即,如果使用serial
类型来创建表,则这应该全部起作用:
CREATE TABLE t1 (id serial,name varchar(20)
);SELECT pg_get_serial_sequence('t1', 'id'); -- returns 't1_id_seq'-- reset the sequence, regardless whether table has rows or not:
SELECT setval(pg_get_serial_sequence('t1', 'id'), coalesce(max(id),0) + 1, false) FROM t1;
但是,如果手动添加了序列:
CREATE TABLE t2 (id integer NOT NULL,name varchar(20)
);CREATE SEQUENCE t2_custom_id_seqSTART WITH 1INCREMENT BY 1NO MINVALUENO MAXVALUECACHE 1;ALTER TABLE t2 ALTER COLUMN id SET DEFAULT nextval('t2_custom_id_seq'::regclass);ALTER SEQUENCE t2_custom_id_seq OWNED BY t2.id; -- required for pg_get_serial_sequenceSELECT pg_get_serial_sequence('t2', 'id'); -- returns 't2_custom_id_seq'-- reset the sequence, regardless whether table has rows or not:
SELECT setval(pg_get_serial_sequence('t2', 'id'), coalesce(max(id),0) + 1, false) FROM t1;
#14楼
重设所有公开序列
CREATE OR REPLACE FUNCTION "reset_sequence" (tablename text) RETURNS "pg_catalog"."void" AS
$body$ DECLARE BEGIN EXECUTE 'SELECT setval( ''' || tablename || '_id_seq'', ' || '(SELECT id + 1 FROM "' || tablename || '" ORDER BY id DESC LIMIT 1), false)'; END;
$body$ LANGUAGE 'plpgsql';select sequence_name, reset_sequence(split_part(sequence_name, '_id_seq',1)) from information_schema.sequenceswhere sequence_schema='public';
#15楼
这个答案是毛罗的副本。
drop function IF EXISTS rebuilt_sequences() RESTRICT;
CREATE OR REPLACE FUNCTION rebuilt_sequences() RETURNS integer as
$body$DECLARE sequencedefs RECORD; c integer ;BEGINFOR sequencedefs IN SelectDISTINCT(constraint_column_usage.table_name) as tablename,constraint_column_usage.column_name as columnname,replace(replace(columns.column_default,'''::regclass)',''),'nextval(''','') as sequencenamefrom information_schema.constraint_column_usage, information_schema.columnswhere constraint_column_usage.table_schema ='public' AND columns.table_schema = 'public' AND columns.table_name=constraint_column_usage.table_nameAND constraint_column_usage.column_name = columns.column_nameAND columns.column_default is not null ORDER BY sequencenameLOOP EXECUTE 'select max('||sequencedefs.columnname||') from ' || sequencedefs.tablename INTO c;IF c is null THEN c = 0; END IF;IF c is not null THEN c = c+ 1; END IF;EXECUTE 'alter sequence ' || sequencedefs.sequencename ||' minvalue '||c ||' start ' || c ||' restart with ' || c;END LOOP;RETURN 1; END;
$body$ LANGUAGE plpgsql;select rebuilt_sequences();
#16楼
我建议在postgres Wiki上找到此解决方案。 它更新表的所有序列。
SELECT 'SELECT SETVAL(' ||quote_literal(quote_ident(PGT.schemaname) || '.' || quote_ident(S.relname)) ||', COALESCE(MAX(' ||quote_ident(C.attname)|| '), 1) ) FROM ' ||quote_ident(PGT.schemaname)|| '.'||quote_ident(T.relname)|| ';'
FROM pg_class AS S,pg_depend AS D,pg_class AS T,pg_attribute AS C,pg_tables AS PGT
WHERE S.relkind = 'S'AND S.oid = D.objidAND D.refobjid = T.oidAND D.refobjid = C.attrelidAND D.refobjsubid = C.attnumAND T.relname = PGT.tablename
ORDER BY S.relname;
使用方法(来自postgres Wiki):
- 将此保存到文件,说“ reset.sql”
- 运行文件并以不包含常规标头的方式保存其输出,然后运行该输出。 例:
例:
psql -Atq -f reset.sql -o temp
psql -f temp
rm temp
原始文章(也有序列所有权的修复程序) 在这里
#17楼
要将所有序列重新启动为1,请使用:
-- Create Function
CREATE OR REPLACE FUNCTION "sy_restart_seq_to_1" (relname TEXT
)
RETURNS "pg_catalog"."void" AS
$BODY$DECLAREBEGINEXECUTE 'ALTER SEQUENCE '||relname||' RESTART WITH 1;';
END;
$BODY$LANGUAGE 'plpgsql';-- Use Function
SELECT relname,sy_restart_seq_to_1(relname)
FROM pg_class
WHERE relkind = 'S';
#18楼
这将使公开的所有序列复位,而无需假设表或列的名称。 在版本8.4上测试
CREATE OR REPLACE FUNCTION "reset_sequence" (tablename text, columnname text, sequence_name text) RETURNS "pg_catalog"."void" AS $body$ DECLARE BEGIN EXECUTE 'SELECT setval( ''' || sequence_name || ''', ' || '(SELECT MAX(' || columnname || ') FROM ' || tablename || ')' || '+1)';END; $body$ LANGUAGE 'plpgsql';select table_name || '_' || column_name || '_seq', reset_sequence(table_name, column_name, table_name || '_' || column_name || '_seq') from information_schema.columns where column_default like 'nextval%';
#19楼
另一个plpgsql-仅在max(att) > then lastval
do --check seq not in sync
$$
declare_r record;_i bigint;_m bigint;
beginfor _r in (SELECT relname,nspname,d.refobjid::regclass, a.attname, refobjidFROM pg_depend dJOIN pg_attribute a ON a.attrelid = d.refobjid AND a.attnum = d.refobjsubidJOIN pg_class r on r.oid = objidJOIN pg_namespace n on n.oid = relnamespaceWHERE d.refobjsubid > 0 and relkind = 'S') loopexecute format('select last_value from %I.%I',_r.nspname,_r.relname) into _i;execute format('select max(%I) from %s',_r.attname,_r.refobjid) into _m;if coalesce(_m,0) > _i thenraise info '%',concat('changed: ',_r.nspname,'.',_r.relname,' from:',_i,' to:',_m);execute format('alter sequence %I.%I restart with %s',_r.nspname,_r.relname,_m+1);end if;end loop;end;
$$
;
还要注释行--execute format('alter sequence
将给出列表,而不是实际重置值
#20楼
我花了一个小时来尝试获得djsnowsill的答案,以便使用混合大小写表和列来处理数据库,然后由于Manuel Darveau的评论,最终偶然发现了该解决方案,但是我想我可以让每个人都更加清楚:
CREATE OR REPLACE FUNCTION "reset_sequence" (tablename text, columnname text)
RETURNS "pg_catalog"."void" AS
$body$
DECLARE
BEGIN
EXECUTE format('SELECT setval(pg_get_serial_sequence(''%1$I'', %2$L),(SELECT COALESCE(MAX(%2$I)+1,1) FROM %1$I), false)',tablename,columnname);
END;
$body$ LANGUAGE 'plpgsql';SELECT format('%s_%s_seq',table_name,column_name), reset_sequence(table_name,column_name)
FROM information_schema.columns WHERE column_default like 'nextval%';
这样做的好处是:
- 不假设ID列的拼写是特定的方式。
- 不假设所有表都有序列。
- 用于混合大小写表/列名称。
- 使用格式更加简洁。
解释一下,问题在于pg_get_serial_sequence
字符串来计算出您所指的内容,因此,如果这样做:
"TableName" --it thinks it's a table or column
'TableName' --it thinks it's a string, but makes it lower case
'"TableName"' --it works!
这是通过在格式字符串中使用''%1$I''
实现的, ''
使撇号1$
表示第一个arg,而I
则用引号引起来
#21楼
使用实体框架创建数据库,然后使用初始数据为数据库添加种子时,会发生此问题,这会使序列不匹配。
我通过创建在种子数据库后运行的脚本来解决该问题:
DO
$do$
DECLARE tablename text;
BEGIN-- change the where statments to include or exclude whatever tables you needFOR tablename IN SELECT table_name FROM information_schema.tables WHERE table_schema='public' AND table_type='BASE TABLE' AND table_name != '__EFMigrationsHistory'LOOPEXECUTE format('SELECT setval(pg_get_serial_sequence(''"%s"'', ''Id''), (SELECT MAX("Id") + 1 from "%s"))', tablename, tablename);END LOOP;
END
$do$
#22楼
克劳斯(Klaus)的答案是最有用的,可能会引起一些误解:您必须在select语句中添加DISTINCT。
但是,如果您确定没有两个表的表名+列名可以相等,则也可以使用:
select sequence_name, --PG_CLASS.relname, PG_ATTRIBUTE.attnamereset_sequence(split_part(sequence_name, '_id_seq',1))
from PG_CLASS
join PG_ATTRIBUTE on PG_ATTRIBUTE.attrelid = PG_CLASS.oid
join information_schema.sequenceson information_schema.sequences.sequence_name = PG_CLASS.relname || '_' || PG_ATTRIBUTE.attname
where sequence_schema='public';
当某些感兴趣的列名不是“ ID”时,这是user457226解决方案的扩展。
#23楼
在我还没有尝试过代码之前:在下面的代码中,我发布了适用于我的PC [Postgres 8.3]的Klaus和user457226解决方案的sql代码版本,对Klaus版本和我的版本进行了一些调整为用户457226之一。
克劳斯解决方案:
drop function IF EXISTS rebuilt_sequences() RESTRICT;
CREATE OR REPLACE FUNCTION rebuilt_sequences() RETURNS integer as
$body$DECLARE sequencedefs RECORD; c integer ;BEGINFOR sequencedefs IN Selectconstraint_column_usage.table_name as tablename,constraint_column_usage.table_name as tablename, constraint_column_usage.column_name as columnname,replace(replace(columns.column_default,'''::regclass)',''),'nextval(''','') as sequencenamefrom information_schema.constraint_column_usage, information_schema.columnswhere constraint_column_usage.table_schema ='public' AND columns.table_schema = 'public' AND columns.table_name=constraint_column_usage.table_nameAND constraint_column_usage.column_name = columns.column_nameAND columns.column_default is not nullLOOP EXECUTE 'select max('||sequencedefs.columnname||') from ' || sequencedefs.tablename INTO c;IF c is null THEN c = 0; END IF;IF c is not null THEN c = c+ 1; END IF;EXECUTE 'alter sequence ' || sequencedefs.sequencename ||' restart with ' || c;END LOOP;RETURN 1; END;
$body$ LANGUAGE plpgsql;select rebuilt_sequences();
user457226解决方案:
--drop function IF EXISTS reset_sequence (text,text) RESTRICT;
CREATE OR REPLACE FUNCTION "reset_sequence" (tablename text,columnname text) RETURNS bigint --"pg_catalog"."void"
AS
$body$DECLARE seqname character varying;c integer;BEGINselect tablename || '_' || columnname || '_seq' into seqname;EXECUTE 'SELECT max("' || columnname || '") FROM "' || tablename || '"' into c;if c is null then c = 0; end if;c = c+1; --because of substitution of setval with "alter sequence"--EXECUTE 'SELECT setval( "' || seqname || '", ' || cast(c as character varying) || ', false)'; DOES NOT WORK!!!EXECUTE 'alter sequence ' || seqname ||' restart with ' || cast(c as character varying);RETURN nextval(seqname)-1;END;
$body$ LANGUAGE 'plpgsql';select sequence_name, PG_CLASS.relname, PG_ATTRIBUTE.attname,reset_sequence(PG_CLASS.relname,PG_ATTRIBUTE.attname)
from PG_CLASS
join PG_ATTRIBUTE on PG_ATTRIBUTE.attrelid = PG_CLASS.oid
join information_schema.sequenceson information_schema.sequences.sequence_name = PG_CLASS.relname || '_' || PG_ATTRIBUTE.attname || '_seq'
where sequence_schema='public';
#24楼
select 'SELECT SETVAL(' || seq [ 1] || ', COALESCE(MAX('||column_name||')+1, 1) ) FROM '||table_name||';'
from (SELECT table_name, column_name, column_default, regexp_match(column_default, '''.*''') as seqfrom information_schema.columnswhere column_default ilike 'nextval%') as sequense_query
#25楼
一种更新模式中用作ID的所有序列的方法:
DO $$ DECLAREr RECORD;
BEGIN
FOR r IN (SELECT tablename, pg_get_serial_sequence(tablename, 'id') as sequencenameFROM pg_catalog.pg_tablesWHERE schemaname='YOUR_SCHEMA'AND tablename IN (SELECT table_name FROM information_schema.columns WHERE table_name=tablename and column_name='id')order by tablename)
LOOP
EXECUTE'SELECT setval(''' || r.sequencename || ''', COALESCE(MAX(id), 1), MAX(id) IS NOT null)FROM ' || r.tablename || ';';
END LOOP;
END $$;
#26楼
只需运行以下命令:
SELECT setval('my_table_seq', (SELECT max(id) FROM my_table));
#27楼
当序列名称,列名称,表名称或模式名称具有有趣的字符(例如空格,标点符号等)时,这些功能将充满风险。 我写了这个:
CREATE OR REPLACE FUNCTION sequence_max_value(oid) RETURNS bigint
VOLATILE STRICT LANGUAGE plpgsql AS $$
DECLAREtabrelid oid;colname name;r record;newmax bigint;
BEGINFOR tabrelid, colname IN SELECT attrelid, attnameFROM pg_attributeWHERE (attrelid, attnum) IN (SELECT adrelid::regclass,adnumFROM pg_attrdefWHERE oid IN (SELECT objidFROM pg_dependWHERE refobjid = $1AND classid = 'pg_attrdef'::regclass)) LOOPFOR r IN EXECUTE 'SELECT max(' || quote_ident(colname) || ') FROM ' || tabrelid::regclass LOOPIF newmax IS NULL OR r.max > newmax THENnewmax := r.max;END IF;END LOOP;END LOOP;RETURN newmax;
END; $$ ;
您可以通过传递OID来为单个序列调用它,它将返回具有默认序列的任何表使用的最高编号; 或者您可以使用类似这样的查询来运行它,以重置数据库中的所有序列:
select relname, setval(oid, sequence_max_value(oid))from pg_classwhere relkind = 'S';
使用不同的质量,您只能重置特定模式中的序列,依此类推。 例如,如果要调整“公共”模式中的序列:
select relname, setval(pg_class.oid, sequence_max_value(pg_class.oid))from pg_class, pg_namespacewhere pg_class.relnamespace = pg_namespace.oid andnspname = 'public' andrelkind = 'S';
请注意,由于setval()的工作原理,您无需在结果中加1。
作为结束语,我必须警告某些数据库似乎具有默认值,这些默认值以不让系统目录包含其完整信息的方式链接到序列。 当您在psql的\\ d中看到类似这样的情况时,就会发生这种情况:
alvherre=# \d bazTabla «public.baz»Columna | Tipo | Modificadores
---------+---------+------------------------------------------------a | integer | default nextval(('foo_a_seq'::text)::regclass)
请注意,除了:: regclass强制转换之外,该默认子句中的nextval()调用还具有:: text强制转换。 我认为这是由于数据库已从旧PostgreSQL版本中进行pg_dump。 将会发生的是,上面的函数sequence_max_value()将忽略该表。 要解决此问题,您可以重新定义DEFAULT子句以直接引用序列而无需强制转换:
alvherre=# alter table baz alter a set default nextval('foo_a_seq');
ALTER TABLE
然后psql正确显示它:
alvherre=# \d bazTabla «public.baz»Columna | Tipo | Modificadores
---------+---------+----------------------------------------a | integer | default nextval('foo_a_seq'::regclass)
解决此问题后,此函数将对该表以及可能使用相同序列的所有其他表正常运行。
#28楼
我的版本使用第一个,并进行一些错误检查...
BEGIN;
CREATE OR REPLACE FUNCTION reset_sequence(_table_schema text, _tablename text, _columnname text, _sequence_name text)
RETURNS pg_catalog.void AS
$BODY$
DECLARE
BEGINPERFORM 1FROM information_schema.sequencesWHEREsequence_schema = _table_schema ANDsequence_name = _sequence_name;IF FOUND THENEXECUTE 'SELECT setval( ''' || _table_schema || '.' || _sequence_name || ''', ' || '(SELECT MAX(' || _columnname || ') FROM ' || _table_schema || '.' || _tablename || ')' || '+1)';ELSERAISE WARNING 'SEQUENCE NOT UPDATED ON %.%', _tablename, _columnname;END IF;
END;
$BODY$LANGUAGE 'plpgsql';SELECT reset_sequence(table_schema, table_name, column_name, table_name || '_' || column_name || '_seq')
FROM information_schema.columns
WHERE column_default LIKE 'nextval%';DROP FUNCTION reset_sequence(_table_schema text, _tablename text, _columnname text, _sequence_name text) ;
COMMIT;
当postgres的主键序列不同步时,如何重置?相关推荐
- python numpy np.lexsort()(使用键序列执行间接稳定排序)(具体没太搞懂区别?)
from numpy\core_multiarray_umath.py @array_function_from_c_func_and_dispatcher(_multiarray_umath.lex ...
- Transactional Replication2:在Subscriber中,主键列是只读的
在使用Transactional Replication时,Subscriber 被认为是"Read-Only"的 , All data at the Subscriber is ...
- MySql数据库查询表信息/列信息(列ID/列名/数据类型/长度/精度/是否可以为null/默认值/是否自增/是否是主键/列描述)...
查询表信息(表名/表描述): SELECT table_name name,TABLE_COMMENT value FROM INFORMATION_SCHEMA.TABLES WHERE table ...
- Linux下的主辅DNS服务器同步
Linux下的主辅DNS服务器同步 一.系统环境介绍 二.辅助DNS搭建 1.安装yum包 2.设置服务自启 3.编辑dns主配置文件 4.编辑区域文件 5.配置正向文件 6.配置反向文件 7.重启服 ...
- mysql 扫描所有字段_select扫描mysql innodb表时,select只输出主键列,会不会扫描全表?...
题主假定按照主键检索.我们假定是等值查询.范围查询和表遍历情形可以在文末经推导得出. primary key A set of columns-and by implication, the inde ...
- 如何设置自增主键列(历史遗留问题解决)
环境:sql2005 sql语句: create table tb(id int identity(1,1) primary key,col1 int) //创建tb表 设置主键为id 自增 增 ...
- mysql 增加主键列_MySQL添加列、删除列,创建主键等常用操作总结
一. 列常用操作 ① 添加新的一列test_column,并将其作为主键,FIRST将其放在表中第一行,auto_increement是自动增长 alter table test_table add ...
- redis从属服务器执行命令 SLAVEOF NO ONE 将使得这个从属服务器关闭复制功能,并从从属服务器转变回主服务器,原来同步所得的数据集不会被丢弃。
另外,对一个从属服务器执行命令 SLAVEOF NO ONE 将使得这个从属服务器关闭复制功能,并从从属服务器转变回主服务器,原来同步所得的数据集不会被丢弃.
- MySQL主从虚IP_Mysql主从同步时Slave_IO_Running:Connecting ; Slave_SQL_Running:Yes的情况故障排除...
前几天在测试主从服务器Mysql同步时遇到了从数据库显示Slave_IO_Running:Connecting: Slave_SQL_Running:Yes的问题. 下面列举几种可能的错误原因: 1. ...
最新文章
- Linux套接字与虚拟文件系统
- python turtle画熊-Python turtle画图库画姓名实例
- SpringMVC:学习笔记(4)——处理模型数据
- JSP脚本 9大内置对象
- java实型常量用十六进制表示_Java 基本语法
- struts2的漏洞
- 开放课程管理系统(Moodle)的介绍(转)
- 数据集永久下架,微软不是第一个,MIT 也不是最后一个
- zabbix监控SNMP
- docker mysql镜像 使用_docker下MySQL镜像的使用方法
- Python知识点(史上最全)
- 总裁演说思维语言沟通学习心得有哪些
- android手机文件管理器,4 款 Android 文件管理器,总有一款适合你
- appium自动注册完整脚本
- javaweb医院科室管理系统springboot
- jude(java建模软件)_JUDE(JAVA建模软件)
- 软件测试思维总结(2)-----跳跃性思维:不按套路出牌
- UE4(unreal Engine)中使用蓝图类Actor创建开关门,并使用鼠标和键盘控制开关门
- 微信小程序毕业设计健康食谱菜谱系统微信小程序+后台管理系统|前后分离VUE.js
- 电脑知识 小技巧汇总