postgres에서 시퀀스를 재설정하고 ID 열을 새 데이터로 채우는 방법은 무엇입니까?
저는 100만 줄이 넘는 테이블을 가지고 있습니다.시퀀스를 재설정하고 새 값(1, 2, 3, 4 등)으로 id 열을 재할당해야 합니다.그렇게 하는 쉬운 방법이 있습니까?
ID의 순서를 유지하지 않으려면 다음과 같이 하십시오.
ALTER SEQUENCE seq RESTART WITH 1;
UPDATE t SET idcolumn=nextval('seq');
테이블 전체를 다시 만들지 않고 선택한 순서대로 쉽게 할 수 있는 방법이 있는지 의심스럽습니다.
포함SQL 8 이상을 사용하면 SQL 8.4 또버은다지를 .WITH 1
더상이기. 의에시로 기록된 .CREATE SEQUENCE
또는 마지막 설정자ALTER SEQUENCE START WITH
사용될 것입니다(아마도 이것은 1일 것입니다).
시퀀스를 재설정합니다.
ALTER SEQUENCE seq RESTART;
그런 다음 테이블의 ID 열을 업데이트합니다.
UPDATE foo SET id = DEFAULT;
시퀀스를 재설정합니다.
SELECT setval('sequence_name', 0);
현재 레코드 업데이트 중:
UPDATE foo SET id = DEFAULT;
1번부터 다시 시작하도록 시퀀스를 재설정하는 가장 좋은 방법은 다음을 실행하는 것입니다.
ALTER SEQUENCE <tablename>_<id>_seq RESTART WITH 1
예를 들어 사용자 테이블의 경우 다음과 같습니다.
ALTER SEQUENCE users_id_seq RESTART WITH 1
시퀀스를 재설정하기 위한 ALTER SEQUENCE 및 SELECT Setval의 적절한 사용을 단순화하고 명확히 하기 위해서만:
ALTER SEQUENCE sequence_name RESTART WITH 1;
와 동등합니다.
SELECT setval('sequence_name', 1, FALSE);
두 문 중 하나를 사용하여 시퀀스를 재설정할 수 있으며, 다음과 같이 nextval('sequence_name')로 다음 값을 얻을 수 있습니다.
nextval('sequence_name')
제공된 두 가지 솔루션 모두 저에게는 효과가 없었습니다.
> SELECT setval('seq', 0);
ERROR: setval: value 0 is out of bounds for sequence "seq" (1..9223372036854775807)
setval('seq', 1)
2로 하고, 번호 매기기는 2로 시작합니다.ALTER SEQUENCE seq START 1
.is seq.is _called true(Postgres 버전 9.0.4)이기 때문에 합니다.
효과적인 솔루션은 다음과 같습니다.
> ALTER SEQUENCE seq RESTART WITH 1;
> UPDATE foo SET id = DEFAULT;
행 순서를 유지하는 방법
UPDATE thetable SET rowid=col_serial FROM
(SELECT rowid, row_number() OVER ( ORDER BY lngid) AS col_serial FROM thetable ORDER BY lngid) AS t1
WHERE thetable.rowid=t1.rowid;
SELECT SETVAL('seq_my_table_pk_id', (SELECT MAX(my_table_pk_id) + 1 FROM my_table));
참고: ID 범위(예: 256 - 10000000) 사이에 새 시작 값을 지정해야 하는 경우:
SELECT setval('"Sequence_Name"',
(SELECT coalesce(MAX("ID"),255)
FROM "Table_Name"
WHERE "ID" < 10000000 and "ID" >= 256)+1
);
시퀀스를 재설정하고 모든 행을 업데이트하는 것만으로도 중복 ID 오류가 발생할 수 있습니다.대부분의 경우 모든 행을 두 번 업데이트해야 합니다.먼저 중복을 방지하기 위해 ID가 높은 경우, 그 다음에 실제로 원하는 ID를 사용합니다.
모든 ID에 고정 금액을 추가하지 마십시오(다른 의견에서 권장됨).이 고정된 양보다 더 많은 행이 있으면 어떻게 됩니까?시퀀스의 다음 값이 기존 행의 모든 id보다 높다고 가정하면(단, 공백을 채우려는 경우), 다음과 같이 수행합니다.
UPDATE table SET id = DEFAULT;
ALTER SEQUENCE seq RESTART;
UPDATE table SET id = DEFAULT;
저의 경우 다음을 통해 이를 달성했습니다.
ALTER SEQUENCE table_tabl_id_seq RESTART WITH 6;
내 테이블이 테이블로 명명된 위치
예를 들어, "FIELD_"의 최대값을 사용하여 시퀀스 "SEQ_A"의 값을 업데이트하려면테이블 "TAB_B"의 ID 필드에서 다음 명령을 사용할 수 있습니다.
SELECT setval('SEQ_A', (SELECT max(FIELD_ID) FROM TAB_B));
이 명령은 "FIELD_"의 최대값을 선택합니다.테이블 "TAB_B"의 ID 필드를 시퀀스 "SEQ_A"의 다음 값으로 설정합니다.
나의 경우 잘못된 sql 파일을 가져온 후 모든 테이블의 시퀀스가 손상되었습니다. SELECT nextval('table_name_id_seq');
는 의 값 보 값 반 습 했 니 다 환 을 작 최 은 대 다 ▁value ▁less ▁of ▁max ▁than ▁the ▁returning ▁was 다 니 습 했 의id
각 를 복구했습니다그래서 각 테이블의 모든 시퀀스를 복구하기 위해 sql 스크립트를 만들었습니다.
DO
$$
DECLARE
rec record;
table_seq text;
BEGIN
FOR rec IN
SELECT *
FROM pg_tables
WHERE tablename NOT LIKE 'pg\_%'
ORDER BY tablename
LOOP
table_seq := rec.tablename || '_id_seq';
RAISE NOTICE '%', table_seq;
EXECUTE format(E'SELECT setval(\'%I\', COALESCE((SELECT MAX(id)+1 FROM %I), 1), false);',
table_seq, rec.tablename);
END LOOP;
END
$$;
참고: 만약 당신이 가지고 있지 않습니다.id
테이블의 열을 사용하면 논리를 업데이트하거나 위의 논리를 기반으로 개별적으로 처리할 수 있습니다.
pgAdmin3을 사용하는 경우 'Sequences'를 확장하고 시퀀스를 마우스 오른쪽 단추로 클릭한 다음 'Properties'로 이동한 다음 'Definition' 탭에서 'Current value'를 원하는 값으로 변경합니다.쿼리가 필요하지 않습니다.
여기 있는 다른 답변에서 영감을 받아 시퀀스 마이그레이션을 수행하는 SQL 함수를 만들었습니다.함수는 기본 키 시퀀스를 기존 시퀀스 범위 내 또는 외부의 값(>= 1)으로 시작하는 새 연속 시퀀스로 이동합니다.
스키마는 같지만 값이 다른 두 데이터베이스를 하나의 데이터베이스로 마이그레이션할 때 이 기능을 어떻게 사용했는지 설명합니다.
첫째, 함수(생성된 SQL 명령을 인쇄하여 실제로 무슨 일이 일어나고 있는지 명확하게 함):
CREATE OR REPLACE FUNCTION migrate_pkey_sequence
( arg_table text
, arg_column text
, arg_sequence text
, arg_next_value bigint -- Must be >= 1
)
RETURNS int AS $$
DECLARE
result int;
curr_value bigint = arg_next_value - 1;
update_column1 text := format
( 'UPDATE %I SET %I = nextval(%L) + %s'
, arg_table
, arg_column
, arg_sequence
, curr_value
);
alter_sequence text := format
( 'ALTER SEQUENCE %I RESTART WITH %s'
, arg_sequence
, arg_next_value
);
update_column2 text := format
( 'UPDATE %I SET %I = DEFAULT'
, arg_table
, arg_column
);
select_max_column text := format
( 'SELECT coalesce(max(%I), %s) + 1 AS nextval FROM %I'
, arg_column
, curr_value
, arg_table
);
BEGIN
-- Print the SQL command before executing it.
RAISE INFO '%', update_column1;
EXECUTE update_column1;
RAISE INFO '%', alter_sequence;
EXECUTE alter_sequence;
RAISE INFO '%', update_column2;
EXECUTE update_column2;
EXECUTE select_max_column INTO result;
RETURN result;
END $$ LANGUAGE plpgsql;
수migrate_pkey_sequence
에서는 다음 인수를 사용합니다.
arg_table
이름 테이이예름블예()'example'
)arg_column
키열 이름 기키 열예이름본예(름:▁(이▁name▁key▁primary▁column열e)'id'
)arg_sequence
name : 예름이스시퀀예(:름)'example_id_seq'
)arg_next_value
후 은 다음과 같습니다.
다음 작업을 수행합니다.
- 기본 키 값을 자유 범위로 이동합니다. 마아일 것입니다.
nextval('example_id_seq')
뒤르는에max(id)
순서가 1로 시작한다는 것입니다.이것은 또한 다음과 같은 경우를 처리합니다.arg_next_value > max(id)
. - 키 을 다으로시기본키값인이범동다니로 합니다.
arg_next_value
키 값의 순서는 보존되지만 범위의 구멍은 보존되지 않습니다. - 순서 뒤에 오는 다음 값을 인쇄합니다.다른 테이블의 열을 마이그레이션하고 이 테이블과 병합하려는 경우 유용합니다.
다음과 다과같이정예시표시사연다니합여하용를와스퀀음의된예▁defined(:▁to다니시연합▁and▁we▁sequence▁a▁tableate,e:psql
):
# CREATE SEQUENCE example_id_seq
START WITH 1
INCREMENT BY 1
NO MINVALUE
NO MAXVALUE
CACHE 1;
# CREATE TABLE example
( id bigint NOT NULL DEFAULT nextval('example_id_seq'::regclass)
);
그런 다음 다음 몇 가지 값을 삽입합니다(예: 3부터 시작).
# ALTER SEQUENCE example_id_seq RESTART WITH 3;
# INSERT INTO example VALUES (DEFAULT), (DEFAULT), (DEFAULT);
-- id: 3, 4, 5
마지막으로, 우리는 마이그레이션합니다.example.id
값을 입력합니다.
# SELECT migrate_pkey_sequence('example', 'id', 'example_id_seq', 1);
INFO: 00000: UPDATE example SET id = nextval('example_id_seq') + 0
INFO: 00000: ALTER SEQUENCE example_id_seq RESTART WITH 1
INFO: 00000: UPDATE example SET id = DEFAULT
migrate_pkey_sequence
-----------------------
4
(1 row)
결과:
# SELECT * FROM example;
id
----
1
2
3
(3 rows)
자동 증분 열이 PK가 아닌 경우에도(이 예에서는 seq -aka sequence라고 함) 트리거를 사용하여 이를 달성할 수 있습니다.
devops_guide 캐스케이드가 존재하는 경우 드롭 테이블;
SELECT 'create the "devops_guide" table'
;
CREATE TABLE devops_guide (
guid UUID NOT NULL DEFAULT gen_random_uuid()
, level integer NULL
, seq integer NOT NULL DEFAULT 1
, name varchar (200) NOT NULL DEFAULT 'name ...'
, description text NULL
, CONSTRAINT pk_devops_guide_guid PRIMARY KEY (guid)
) WITH (
OIDS=FALSE
);
-- START trg_devops_guide_set_all_seq
CREATE OR REPLACE FUNCTION fnc_devops_guide_set_all_seq()
RETURNS TRIGGER
AS $$
BEGIN
UPDATE devops_guide SET seq=col_serial FROM
(SELECT guid, row_number() OVER ( ORDER BY seq) AS col_serial FROM devops_guide ORDER BY seq) AS tmp_devops_guide
WHERE devops_guide.guid=tmp_devops_guide.guid;
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
CREATE TRIGGER trg_devops_guide_set_all_seq
AFTER UPDATE OR DELETE ON devops_guide
FOR EACH ROW
WHEN (pg_trigger_depth() < 1)
EXECUTE PROCEDURE fnc_devops_guide_set_all_seq();
언급URL : https://stackoverflow.com/questions/4678110/how-to-reset-sequence-in-postgres-and-fill-id-column-with-new-data
'programing' 카테고리의 다른 글
Azure Container 인스턴스와 Web App for Container의 차이점은 무엇입니까? (0) | 2023.05.09 |
---|---|
바이트 배열을 문자열로 변환하는 방법 (0) | 2023.05.09 |
Eclipse 프로젝트에서 일부 폴더를 제외하려면 어떻게 해야 합니까? (0) | 2023.05.09 |
Git, 이전 커밋 사용자 이름 및 이메일 다시 쓰기 (0) | 2023.05.09 |
WPF: 사용자 컨트롤에 표시되는 대화 상자의 소유자 창을 설정하려면 어떻게 해야 합니까? (0) | 2023.05.09 |