आप करने के लिए अपना कोड बदल सकते हैं:
v_lstmt := 'SELECT count(*) FROM userB.tableB WHERE id = '''||v_ret (i).id||''''
|| ' and ('||v_ret (i).col||' is null or '||v_ret (i).col||' = :val)';
EXECUTE IMMEDIATE v_lstmt INTO cDel using v_ret (i).val;
यह जांचता है कि कॉलम शून्य है या आपूर्ति किए गए val
. से मेल खाता है , और पार्सिंग को थोड़ा कम करने के लिए जांच करने के लिए मूल्य की आपूर्ति करने के लिए एक बाइंड वैरिएबल का उपयोग करता है।
हालांकि यह अभी भी निहित रूपांतरण पर निर्भर करता है, इसलिए यदि आपके पास तालिका में दिनांक मान था, उदाहरण के लिए आप लक्ष्य तालिका कॉलम प्रकार से मेल खाने के लिए इसे परिवर्तित करने के लिए अपनी एनएलएस सेटिंग्स पर निर्भर होंगे।
आप all_tab_columns
. का उपयोग कर सकते हैं लक्ष्य स्तंभ के डेटा प्रकार को खोजने के लिए देखें और val
. का स्पष्ट रूपांतरण करें बाध्यकारी से पहले उस प्रकार के लिए। dbms_sql
. का उपयोग करने के लिए एक अधिक शामिल लेकिन संभवतः अधिक मजबूत दृष्टिकोण होगा execute immediate
. के बजाय आंतरिक गतिशील SQL के लिए ।
ऐसा लगता है कि बाहरी क्वेरी को गतिशील होने की आवश्यकता नहीं है, हालांकि आप ऐसा कर सकते हैं:
declare
v_lstmt VARCHAR2(32000);
cDel number;
begin
for rec in (SELECT id, col, val FROM tableA) loop
v_lstmt := 'SELECT count(*) FROM tableB WHERE id = '''||rec.id||''''
|| ' and ('||rec.col||' is null or '||rec.col||' = :val)';
dbms_output.put_line(v_lstmt);
EXECUTE IMMEDIATE v_lstmt INTO cDel using rec.val;
If cDel > 0 Then
--some code
cDel := 0;
end if;
end loop;
end;
/