এখানে অন্যান্য উত্তরের দ্বারা অনুপ্রাণিত হয়ে, আমি একটি ক্রম মাইগ্রেশন করার জন্য একটি এসকিউএল ফাংশন তৈরি করেছি। ফাংশনটি একটি প্রাথমিক কী সিকোয়েন্সকে কোনও নতুন মান (> = 1) দ্বারা বিদ্যমান সিকোয়েন্সের ব্যাপ্তির ভিতরে বা বাইরে শুরু করে একটি নতুন সাবলীল সিকোয়েন্সে নিয়ে যায়।
আমি এখানে ব্যাখ্যা করছি যে আমি কীভাবে একই স্কিমার সাথে দুটি ডাটাবেসের স্থানান্তরিত করতে কিন্তু এই একই ফাংশনটি একটি ডাটাবেসে বিভিন্ন মান ব্যবহার করেছি।
প্রথমত, ফাংশন (যা উত্পন্ন এসকিউএল কমান্ডগুলি প্রিন্ট করে যাতে প্রকৃতপক্ষে কী ঘটছে তা পরিষ্কার হয়ে যায়):
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 দিয়ে শুরু হয় This এটি যেখানে কেস পরিচালনা করে 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)