এটি বাস্তবায়নের সিদ্ধান্ত। এটি পোস্টগ্রিস ডকুমেন্টেশন, WITH
ক্যোরিজ (সাধারণ টেবিল এক্সপ্রেশন) -এ বর্ণনা করা হয়েছে । বিষয়টি সম্পর্কিত দুটি অনুচ্ছেদ রয়েছে are
প্রথমত, পর্যবেক্ষণ আচরণের কারণ:
এর উপ-বিবৃতিগুলিWITH
একে অপরের সাথে এবং মূল ক্যোয়ারির সাথে একযোগে কার্যকর করা হয় । সুতরাং, ডেটা-সংশোধনকারী বিবৃতিগুলিতে ব্যবহার WITH
করার সময়, নির্দিষ্ট আপডেটগুলি আসলে যে ক্রমে ঘটে তা অনাকাঙ্ক্ষিত। সমস্ত বিবৃতি একই স্ন্যাপশট দিয়ে চালিত হয় (অধ্যায় 13 দেখুন), তাই তারা লক্ষ্য সারণিতে একে অপরের প্রভাব "দেখতে" পারে না। এটি সারি আপডেটগুলির আসল ক্রমের অনিশ্চয়তার প্রভাবগুলি হ্রাস করে এবং এর অর্থ হ'ল RETURNING
ডেটা হ'ল বিভিন্ন WITH
উপ-বিবৃতি এবং মূল ক্যোয়ারির মধ্যে পরিবর্তনগুলি যোগাযোগ করার একমাত্র উপায় । এর উদাহরণ হ'ল ...
আমি পিগএসকিএল-ডক্সের সাথে একটি পরামর্শ পোস্ট করার পরে , মার্কো তিক্কাজা ব্যাখ্যা করেছিলেন (যা এরউইনের উত্তরের সাথে একমত):
সন্নিবেশ-আপডেট এবং সন্নিবেশ-মোছার কেসগুলি কার্যকর হয় না কারণ আপডেটগুলি এবং মোছার ক্ষেত্রে INSERT হওয়ার আগে স্ন্যাপশট নেওয়া হওয়ার কারণে INSERTed সারিগুলি দেখার কোনও উপায় নেই। এই দুটি মামলা নিয়ে অপ্রত্যাশিত কিছুই নেই।
সুতরাং আপনার বিবৃতিটি আপডেট না হওয়ার কারণটি উপরের প্রথম অনুচ্ছেদে (প্রায় "স্ন্যাপশট") দ্বারা ব্যাখ্যা করা যেতে পারে। আপনি যখন সিটিইগুলিকে সংশোধন করবেন তখন যা ঘটে তা হ'ল এগুলি এবং মূল ক্যোয়ারী কার্যকর করা হয় এবং ডেটা (টেবিল) এর একই স্ন্যাপশটটি "দেখুন", যেমন তারা বিবৃতি কার্যকর করার আগেই ছিল। সিটিইগুলি ক্লোজটি ব্যবহার করে তারা কীভাবে একে অপরকে সন্নিবেশিত / আপডেট / মুছে ফেলা হয়েছে তার তথ্য পাস করতে পারে RETURNING
তবে তারা টেবিলের পরিবর্তনগুলি সরাসরি দেখতে পাবে না। সুতরাং আসুন আপনার বিবৃতিতে কী ঘটে তা দেখতে দিন:
WITH newval AS (
INSERT INTO tbl(val) VALUES (1) RETURNING id
) UPDATE tbl SET val=2 FROM newval WHERE tbl.id=newval.id;
আমাদের দুটি অংশ রয়েছে, সিটিই ( newval
):
-- newval
INSERT INTO tbl(val) VALUES (1) RETURNING id
এবং মূল প্রশ্ন:
-- main
UPDATE tbl SET val=2 FROM newval WHERE tbl.id=newval.id
মৃত্যুদন্ড কার্যকর করার প্রবাহ এইরকম:
initial data: tbl
id │ val
(empty)
/ \
/ \
/ \
newval: \
tbl (after newval) \
id │ val \
1 │ 1 |
|
newval: returns |
id |
1 |
\ |
\ |
\ |
main query
ফলস্বরূপ, যখন প্রধান ক্যোয়ারী টেবিলের tbl
সাথে (স্ন্যাপশটে দেখা যায়) newval
যোগদান করে, এটি একটি 1-সারির টেবিলের সাথে খালি টেবিলে যোগ দেয়। স্পষ্টতই এটি 0 টি সারি আপডেট করে। সুতরাং বিবৃতিটি আসলে কখনই সন্নিবেশ করা সারিটি সংশোধন করতে আসেনি এবং এটিই আপনি দেখছেন।
আপনার ক্ষেত্রে সমাধানটি হ'ল হয় প্রথমে সঠিক মানগুলি সন্নিবেশ করানোর জন্য বিবৃতিটি পুনর্লিখন করা বা 2 টি স্টেটমেন্ট ব্যবহার করা। একটি যা সন্নিবেশ করায় এবং দ্বিতীয়টি আপডেট করতে।
অন্যান্য, অনুরূপ পরিস্থিতি রয়েছে, যেমন যদি বিবৃতিটির একই সারিগুলিতে একটি INSERT
এবং তারপরে একটি DELETE
থাকে। মুছে ফেলা ঠিক একই কারণে ব্যর্থ হবে।
আপডেট-আপডেট এবং আপডেট-ডিলিট সহ আরও কয়েকটি মামলা এবং তাদের আচরণ একই ডক্স পৃষ্ঠায় নিম্নলিখিত অনুচ্ছেদে বর্ণিত হয়েছে।
একক বিবৃতিতে একই সারিতে দুবার আপডেট করার চেষ্টা করা সমর্থনযোগ্য নয়। কেবলমাত্র একটি পরিবর্তন ঘটেছে, তবে কোনটি নির্ভরযোগ্যভাবে পূর্বাভাস দেওয়া সহজ (এবং কখনও কখনও সম্ভব নয়)। এটি একই বিবৃতিতে ইতিমধ্যে আপডেট হওয়া একটি সারি মুছে ফেলার ক্ষেত্রেও প্রযোজ্য: কেবলমাত্র আপডেটটি সম্পাদিত হয়। অতএব আপনার একক বিবৃতিতে সাধারণত একবারে একটি সারিতে সংশোধন করার চেষ্টা করা এড়ানো উচিত। বিশেষত উপ-বিবৃতিগুলি লিখে এড়িয়ে চলুন যা মূল বক্তব্য বা ভাইবোন সাব-স্টেটমেন্ট দ্বারা পরিবর্তিত একই সারিগুলিকে প্রভাবিত করতে পারে। এই জাতীয় বক্তব্যের প্রভাবগুলি অনুমানযোগ্য হবে না।
এবং মার্কো টিইককাজার উত্তরে:
আপডেটের-আপডেট এবং আপডেট-Delete ক্ষেত্রে স্পষ্টভাবে হয় না একই অন্তর্নিহিত বাস্তবায়ন বিস্তারিত (সন্নিবেশ-আপডেট এবং সন্নিবেশ-Delete ক্ষেত্রে হিসাবে) দ্বারা সৃষ্ট।
আপডেট-আপডেটের মামলাটি কার্যকর হয় না কারণ এটি অভ্যন্তরীণভাবে হ্যালোইন সমস্যার মতো দেখায় এবং পোস্টগ্রিসের জানার কোনও উপায় নেই যে কোন টিপলগুলি দু'বার আপডেট করা ঠিক হবে এবং কোনটি হ্যালোইন সমস্যার পুনঃপ্রবর্তন করতে পারে।
সুতরাং কারণটি একই (সিটিই কীভাবে পরিবর্তন করা হয় এবং প্রতিটি সিটিই একই স্ন্যাপশটটি কীভাবে দেখায়) তবে বিবরণগুলি এই 2 টি ক্ষেত্রে পৃথক, কারণ এটি আরও জটিল এবং ফলাফল আপডেট-আপডেটের ক্ষেত্রে অনাকাঙ্ক্ষিত হতে পারে।
সন্নিবেশ-আপডেটে (আপনার ক্ষেত্রে হিসাবে) এবং অনুরূপ সন্নিবেশ-মুছলে ফলাফল অনুমানযোগ্য। সদ্য সন্নিবেশ করা সারিগুলি দেখার এবং প্রভাবিত করার জন্য দ্বিতীয় ক্রিয়াকলাপের (আপডেট বা মুছুন) কোনও উপায় না থাকায় কেবল সন্নিবেশ ঘটে।
প্রস্তাবিত সমাধানটি সকল ক্ষেত্রে একইরূপে একই পাতাগুলিকে একাধিকবার সংশোধন করার চেষ্টা করে: এটি করবেন না। হয় বিবৃতি লিখুন যা প্রতিটি সারি একবারে সংশোধন করে অথবা পৃথক (2 বা আরও) বিবৃতি ব্যবহার করে।