একটি নমুনা টেবিল এবং ডেটা
CREATE TABLE dupes(col1 int primary key, col2 int, col3 text,
CONSTRAINT col2_unique UNIQUE (col2)
);
INSERT INTO dupes values(1,1,'a'),(2,2,'b');
সমস্যা পুনরুত্পাদন
INSERT INTO dupes values(3,2,'c')
ON CONFLICT (col1) DO UPDATE SET col3 = 'c', col2 = 2
এই কিউ 1 কল করুন। ফলাফল হলো
ERROR: duplicate key value violates unique constraint "col2_unique"
DETAIL: Key (col2)=(2) already exists.
দ্বন্দ্ব_তারজিটি অনন্য সূচি অনুমান করতে পারে। অনুমান সম্পাদন করার সময়, এটিতে এক বা একাধিক সূচি_ কলাম_নাম কলাম এবং / অথবা সূচক_প্রকাশ এক্সপ্রেশন এবং একটি alচ্ছিক সূচক_প্রকাশ থাকে। অর্ডার বিবেচনা না করে, সমস্ত সারণী-নাম অনন্য সূচীগুলিতে ঠিক দ্বন্দ্ব_তার্গেট-নির্দিষ্ট কলাম / এক্সপ্রেশন থাকে সালিস সূচক হিসাবে অনুমান করা (নির্বাচিত)। যদি একটি সূচক_প্রেডিকেট নির্দিষ্ট করা থাকে তবে এটি অবশ্যই অনুমানের প্রয়োজন হিসাবে আরবিটার সূচকগুলি সন্তুষ্ট করতে হবে।
এটি এই ধারণাটি দেয় যে নিম্নলিখিত কোয়েরিতে কাজ করা উচিত, তবে এটি হ'ল না কারণ এটির জন্য আসলে কল 1 এবং কল 2 এ একসাথে অনন্য সূচক প্রয়োজন। তবে এই জাতীয় সূচক গ্যারান্টি দেয় না যে কল 1 এবং কল 2 স্বতন্ত্রভাবে অনন্য হবে যা অপের প্রয়োজনীয়তার একটি।
INSERT INTO dupes values(3,2,'c')
ON CONFLICT (col1,col2) DO UPDATE SET col3 = 'c', col2 = 2
আসুন এই ক্যোয়ারী Q2 কল করুন (এটি একটি সিনট্যাক্স ত্রুটির সাথে ব্যর্থ হয়)
কেন?
পোস্টগ্র্যাস্কলটি এইভাবে আচরণ করে কারণ দ্বিতীয় কলামে যখন কোনও বিরোধ দেখা দেয় তখন কী হওয়া উচিত তা সঠিকভাবে সংজ্ঞায়িত হয় না। সম্ভাবনার সংখ্যা রয়েছে। উদাহরণস্বরূপ উপরের Q1 ক্যোয়ারিতে, col1
কোনও বিরোধ চলাকালীন পোস্টগ্রেসকিএল আপডেট করা উচিত col2
? কিন্তু যদি তা অন্য বিরোধের দিকে পরিচালিত করে তবে কী হবে col1
? পোস্টগ্র্যাস্কেল কীভাবে এটি পরিচালনা করবে?
একটি সমাধান
একটি সমাধানটি পুরানো ফ্যাশনযুক্ত ইউপিএসআরটির সাথে কনফ্লিক্টকে একত্রিত করা ।
CREATE OR REPLACE FUNCTION merge_db(key1 INT, key2 INT, data TEXT) RETURNS VOID AS
$$
BEGIN
LOOP
UPDATE dupes SET col3 = data WHERE col1 = key1 and col2 = key2;
IF found THEN
RETURN;
END IF;
BEGIN
INSERT INTO dupes VALUES (key1, key2, data) ON CONFLICT (col1) DO UPDATE SET col3 = data;
RETURN;
EXCEPTION WHEN unique_violation THEN
BEGIN
INSERT INTO dupes VALUES (key1, key2, data) ON CONFLICT (col2) DO UPDATE SET col3 = data;
RETURN;
EXCEPTION WHEN unique_violation THEN
END;
END;
END LOOP;
END;
$$
LANGUAGE plpgsql;
আপনার এই সঞ্চিত ফাংশনের যুক্তিটি সংশোধন করতে হবে যাতে এটি কলামগুলি ঠিক যেভাবে চান তা আপডেট করে। এটি পছন্দ করুন
SELECT merge_db(3,2,'c');
SELECT merge_db(1,2,'d');