आपको यहां कुछ समस्याएं हैं, जिनमें शामिल हैं:
IN_DATE
एक तिथि के रूप में घोषित किया गया है, इसलिए आपको इसेTO_DATE()
. के माध्यम से पारित करने की आवश्यकता नहीं है ।- आपको केवल एक कर्सर लूप चाहिए; अगर आप किसी
employee_id
. के लिए सभी अपडेट संसाधित करना चाहते हैं किसी कारण से आप एक साथorder by
जोड़ सकते हैं खंड। - आपको डायनेमिक SQL की बिल्कुल भी आवश्यकता नहीं है; आप स्थिर SQL अद्यतन के भाग के रूप में कर्सर के मानों का उपयोग कर सकते हैं।
तो सिंगल लूप वाला एक साधारण संस्करण कुछ इस तरह दिख सकता है:
CREATE OR REPLACE PROCEDURE sp_run_employee_updates (p_date IN DATE) IS
CURSOR c_updates IS
SELECT *
FROM bi_employee_update
WHERE effective_date = p_date
AND executed = 'N'
AND activity_id = '0'
FOR UPDATE;
BEGIN
-- loop around all pending records
FOR r_update IN c_updates LOOP
-- apply this update to the bi_employee record
UPDATE bi_employee
SET col1 = r_update.col1, col2 = r_update.col2
WHERE emp_id = r_update.employee_id;
-- mark this update as executed
UPDATE bi_employee_update
SET executed = 'Y'
WHERE CURRENT OF c_updates;
END LOOP;
END sp_run_employee_updates;
यह for update
. का उपयोग कर रहा है और where current of
आप जिस पंक्ति के साथ काम कर रहे हैं उसे लॉक करने और अद्यतन को सरल बनाने के लिए दोनों का निर्माण करता है; दस्तावेज़ देखें यहां
।
यह ध्यान देने योग्य है कि यदि या तो effective_date
या p_date
एक समय घटक है जो वे मेल नहीं खाएंगे। p_date
के लिए इसकी संभावना नहीं है , लेकिन effective_date
के लिए अनुमान लगाना कठिन है . यदि ऐसा होता है तो आपको या तो trunc()
. की आवश्यकता होगी इसे, या between
. का उपयोग करें कई बार देखने के लिए।