CREATE TABLE IF NOT EXISTS meeting_number_counter ( period_ym CHAR(7) PRIMARY KEY, last_value INTEGER NOT NULL DEFAULT 0, updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW() ); CREATE OR REPLACE FUNCTION next_meeting_number(p_date DATE DEFAULT CURRENT_DATE) RETURNS TEXT LANGUAGE plpgsql AS $$ DECLARE v_period TEXT; v_seq INTEGER; BEGIN v_period := TO_CHAR(p_date, 'YYYY_MM'); LOOP UPDATE meeting_number_counter SET last_value = last_value + 1, updated_at = NOW() WHERE period_ym = v_period RETURNING last_value INTO v_seq; IF FOUND THEN EXIT; END IF; BEGIN INSERT INTO meeting_number_counter(period_ym, last_value) VALUES (v_period, 1); v_seq := 1; EXIT; EXCEPTION WHEN unique_violation THEN -- paralleler Insert, erneut versuchen END; END LOOP; RETURN 'SITZ-' || v_period || '_' || LPAD(v_seq::TEXT, 4, '0'); END; $$; UPDATE meeting SET meeting_number = next_meeting_number(COALESCE(meeting_date, CURRENT_DATE)) WHERE meeting_number IS NULL OR TRIM(meeting_number) = ''; ALTER TABLE meeting ALTER COLUMN meeting_number SET DEFAULT next_meeting_number(); ALTER TABLE meeting ALTER COLUMN meeting_number SET NOT NULL;