호출 예시

CALL RESET_ALL_SERIALS();
CALL RESET_ALL_SERIALS('스키마명');
CALL RESET_ALL_SERIALS('스키마명', '테이블명');

정의

-- ---------------------------------------------------------------------------------------------
-- 스키마(or 테이블) 내 모든 Serial 시퀀스 리셋
-- ---------------------------------------------------------------------------------------------
-- 예시
--   - CALL RESET_ALL_SERIALS();
--   - CALL RESET_ALL_SERIALS('스키마명');
--   - CALL RESET_ALL_SERIALS('스키마명', '테이블명');
-- ---------------------------------------------------------------------------------------------
DROP PROCEDURE IF EXISTS RESET_ALL_SERIALS;
CREATE PROCEDURE RESET_ALL_SERIALS
(
    _schema_name TEXT DEFAULT 'public', 
    _table_name  TEXT DEFAULT NULL
)
LANGUAGE plpgsql
AS $$
DECLARE
    sequence_record record;
    table_nm text;
    column_nm text;
    sequence_full_nm text;
    max_id bigint;
    last_seq_val int;
    is_modified text;
BEGIN
    _schema_name = LOWER(_schema_name);
    _table_name = LOWER(_table_name);

    FOR sequence_record IN
        SELECT sequence_name
        FROM information_schema.sequences
        WHERE sequence_schema = _schema_name
    LOOP
        is_modified = ' ';
                
        -- [1] 시퀀스가 사용되는 테이블, 컬럼 이름 탐색
        SELECT column_name, table_name INTO column_nm, table_nm
        FROM information_schema.columns
        WHERE column_default LIKE 'nextval(%' || (sequence_record.sequence_name) || '%)'
          AND table_schema = _schema_name
          AND CASE WHEN _table_name IS NULL THEN (TRUE) 
                   ELSE (table_name = _table_name) END;
        
        -- 해당하는 테이블이 아니면 생략
        CONTINUE WHEN (column_nm IS NULL);
        
        -- 스키마.시퀀스 이름 초기화
        sequence_full_nm := _schema_name || '.' || sequence_record.sequence_name;
        
        -- [2] 현재 값 확인
        EXECUTE FORMAT('SELECT last_value FROM %s', sequence_full_nm) INTO last_seq_val;
        
        -- [3] 해당 테이블에서 최대값 탐색
        EXECUTE 'SELECT COALESCE(MAX(' || quote_ident(column_nm) || '), 0) FROM ' || quote_ident(_schema_name) || '.' || quote_ident(table_nm) INTO max_id;

        IF max_id = 0 THEN
        -- [4-1] 시퀀스 값을 1로 재시작
            IF last_seq_val > 1 THEN
                is_modified = '*';
            END IF;
            EXECUTE(FORMAT('ALTER SEQUENCE %s RESTART WITH 1;', sequence_full_nm));
            RAISE NOTICE '% %.%.% : % => Reset (1)', is_modified, _schema_name, table_nm, column_nm, last_seq_val;
        ELSE
        -- [4-2] 시퀀스 값을 최대값으로 변경
            IF last_seq_val != max_id THEN
                is_modified = '*';
            END IF;
            EXECUTE 'SELECT setval(' || quote_literal(sequence_full_nm) || ', ' || max_id || ', true)';
            RAISE NOTICE '% %.%.% : % => %', is_modified, _schema_name, table_nm, column_nm, last_seq_val, max_id;
        END IF;
    END LOOP;
END; $$;