यहाँ अन्य उत्तरों से प्रेरित होकर, मैंने अनुक्रम प्रवास करने के लिए एक 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
: प्राथमिक कुंजी स्तंभ नाम (उदा 'id'
)
arg_sequence
: अनुक्रम नाम (उदा 'example_id_seq'
)
arg_next_value
: माइग्रेशन के बाद कॉलम के लिए अगला मान
यह निम्नलिखित कार्य करता है:
- प्राथमिक कुंजी मानों को एक मुक्त श्रेणी में ले जाएं। मुझे लगता है कि
nextval('example_id_seq')
इस प्रकार है max(id)
और अनुक्रम 1 के साथ शुरू होता है। यह भी मामले को संभालता है जहां arg_next_value > max(id)
।
- प्राथमिक कुंजी मान को सन्निहित सीमा से शुरू करें
arg_next_value
। प्रमुख मूल्यों का क्रम संरक्षित है लेकिन सीमा में छेद संरक्षित नहीं हैं।
- अगले मूल्य को प्रिंट करें जो अनुक्रम में अनुसरण करेगा। यदि आप किसी अन्य तालिका के स्तंभों को स्थानांतरित करना चाहते हैं और इस एक के साथ विलय करना चाहते हैं तो यह उपयोगी है।
प्रदर्शित करने के लिए, हम एक अनुक्रम और तालिका को निम्नानुसार परिभाषित करते हैं (उदाहरण के लिए 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
1 से शुरू करने के लिए मानों को स्थानांतरित करते हैं।
# 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)