যদি আমার কাছে 3 টি কলামযুক্ত একটি টেবিল থাকে - এ, বি এবং ডি বলুন - এবং আমাকে একটি নতুন প্রবর্তন করতে হয়েছিল - ডি এর বর্তমান অবস্থান প্রতিস্থাপন করতে সি বলুন আমি নিম্নলিখিত পদ্ধতিটি ব্যবহার করব:
- সি এবং ডি 2 হিসাবে 2 টি নতুন কলাম প্রবর্তন করুন।
- ডি 2 এর বিষয়বস্তু অনুলিপি করুন।
- ডি মুছুন
- ডি 2 থেকে ডি নাম পরিবর্তন করুন D.
নতুন আদেশটি হবে এ, বি, সি এবং ডি be
আমি ভেবেছিলাম এটি একটি বৈধ অনুশীলন হিসাবে (এখনও অবধি) এটি কোনও সমস্যা তৈরি করে নি।
যাইহোক, আজ আমি একটি সমস্যার মুখোমুখি হয়েছি যখন একই টেবিলে একটি বিবৃতি বহন করে এমন একটি ফাংশন নিম্নলিখিত ত্রুটিটি ফিরে পেয়েছিল:
table row type and query-specified row type do not match
এবং নিম্নলিখিত বিবরণ:
Query provides a value for a dropped column at ordinal position 13
আমি পোস্টগ্রেএসকিউএল পুনরায় চালু করার চেষ্টা করেছি VACUUM FULL
এবং শেষ পর্যন্ত এখানে এবং এখানে প্রস্তাবিত ফাংশনটি মুছে ফেলা এবং পুনরায় তৈরি করার চেষ্টা করেছি তবে এই সমাধানগুলি কার্যকর হয়নি (এক্ষেত্রে যে কোনও সিস্টেমের টেবিলটি পরিবর্তিত হয়েছে এমন পরিস্থিতি মোকাবিলা করার চেষ্টা করে)।
খুব ছোট একটি ডাটাবেসের সাথে কাজ করার বিলাসিতা থাকা আমি এটিকে রপ্তানি করেছি, এটি মুছে ফেলেছি এবং এটি আবার আমদানি করেছি এবং এটি আমার ফাংশনটির সাথে সমস্যাটি স্থির করেছে ।
আমি এই বিষয়টি সম্পর্কে সচেতন ছিলাম যে এখানে সিস্টেমের সারণীগুলি (হাত দিয়ে নোংরা হওয়া pg_attribute
ইত্যাদি) সংশোধন করে কলামগুলির প্রাকৃতিক শৃঙ্খলা নিয়ে গণ্ডগোল করা উচিত নয় :
পোস্টগ্রিসে কলামগুলির প্রাকৃতিক ক্রম পরিবর্তন করা সম্ভব?
আমার ফাংশনটিতে ফেলে দেওয়া ত্রুটিটি বিচার করে আমি এখন বুঝতে পারি যে আমার পদ্ধতির সাথে কলামগুলির ক্রম স্থানান্তরিত করাও একটি নং। আমি কী করছি সেটাও ভুল কেন কেউ হালকাভাবে আলোকিত করতে পারে?
পোস্টগ্রিজ সংস্করণটি 9.6.0।
ফাংশনটি এখানে:
CREATE OR REPLACE FUNCTION "public"."__post_users" ("facebookid" text, "useremail" text, "username" text) RETURNS TABLE (authentication_code text, id integer, key text, stripe_id text) AS '
-- First, select the user:
WITH select_user AS
(SELECT
users.id
FROM
users
WHERE
useremail = users.email),
-- Second, update the user (if user exists):
update_user AS
(UPDATE
users
SET
authentication_code = GEN_RANDOM_UUID(),
authentication_date = current_timestamp,
facebook_id = facebookid
WHERE EXISTS (SELECT * FROM select_user)
AND
useremail = users.email
RETURNING
users.authentication_code,
users.id,
users.key,
users.stripe_id),
-- Third, insert the user (if user does not exist):
insert_user AS
(INSERT INTO
users (authentication_code, authentication_date, email, key, name, facebook_id)
SELECT
GEN_RANDOM_UUID(),
current_timestamp,
useremail,
GEN_RANDOM_UUID(),
COALESCE(username, SUBSTRING(useremail FROM ''([^@]+)'')),
facebookid
WHERE NOT EXISTS (SELECT * FROM select_user)
RETURNING
users.authentication_code,
users.id,
users.key,
users.stripe_id)
-- Finally, select the authentication code, ID, key and Stripe ID:
SELECT
*
FROM
update_user
UNION ALL
SELECT
*
FROM
insert_user' LANGUAGE "sql" COST 100 ROWS 1
VOLATILE
CALLED ON NULL INPUT
SECURITY INVOKER
আমি উভয় কলামে পুনর্নবীকরণ / পুনঃনির্মাণ সম্পাদন করেছি facebook_id
এবং stripe_id
(এর আগে একটি নতুন কলাম যুক্ত করা হয়েছিল, এটিই নামকরণের কারণ, তবে এই ক্যোয়ারীর দ্বারা স্পর্শ করা হয়নি)।
একটি নির্দিষ্ট ক্রমে কলামগুলি থাকা অর্ডারটির জন্য খাঁটি আগ্রহের বাইরে। তবে এই প্রশ্নটি জিজ্ঞাসা করার কারণটি উদ্বেগের বাইরে যে একটি সাধারণ নামকরণ এবং কলাম মুছে ফেলা প্রডাকশন মোডে কারও কারও জন্য বাস্তব সমস্যাগুলি ট্রিগার করতে পারে (যেমনটি আমার নিজের মতো হয়েছিল)।