यह वास्तव में एक बड़ा विषय है, लेकिन यह वह दृष्टिकोण है जो मुझे लगता है कि लागू करना सबसे आसान है और अच्छी तरह से काम करता है। चाल गतिशील एसक्यूएल का उपयोग करना है, लेकिन इसे लागू करें ताकि आप हमेशा समान पैरामीटर (आवश्यक) पास कर सकें, और जब आप पैरामीटर के लिए कोई मान नहीं रखते हैं तो आप ओरेकल को शॉर्ट-सर्किट की अनुमति देते हैं (आपमें क्या कमी है) आपका वर्तमान दृष्टिकोण)। उदाहरण के लिए:
set serveroutput on
create or replace procedure test_param(p1 in number default null, p2 in varchar2 default null) as
l_sql varchar2(4000);
l_cur sys_refcursor;
l_rec my_table%rowtype;
l_ctr number := 0;
begin
l_sql := 'select * from my_table where 1=1';
if (p1 is not null) then
l_sql := l_sql || ' and my_num_col = :p1';
else
-- short circuit for optimizer (1=1)
l_sql := l_sql || ' and (1=1 or :p1 is null)';
end if;
if (p2 is not null) then
l_sql := l_sql || ' and name like :p2';
else
-- short circuit for optimizer (1=1)
l_sql := l_sql || ' and (1=1 or :p2 is null)';
end if;
-- show what the SQL query will be
dbms_output.put_line(l_sql);
-- note always have same param list (using)
open l_cur for l_sql using p1,p2;
-- could return this cursor (function), or simply print out first 10 rows here for testing
loop
l_ctr := l_ctr + 1;
fetch l_cur
into l_rec;
exit when l_cur%notfound OR l_ctr > 10;
dbms_output.put_line('Name is: ' || l_rec.name || ', Address is: ' || l_rec.address1);
end loop;
close l_cur;
end;
परीक्षण करने के लिए, बस इसे चलाएं। उदाहरण के लिए:
set serveroutput on
-- using 0 param
exec test_param();
-- using 1 param
exec test_param(123456789);
-- using 2 params
exec test_param(123456789, 'ABC%');
मेरे सिस्टम पर, उपयोग की गई तालिका संख्या फ़ील्ड और नाम फ़ील्ड पर एक अनुक्रमणिका के साथ 100 मिमी से अधिक पंक्तियों में है। लगभग तुरंत लौट आता है। यह भी ध्यान दें कि यदि आपको सभी स्तंभों की आवश्यकता नहीं है, तो आप एक चयन * नहीं करना चाहेंगे, लेकिन मैं थोड़ा आलसी हो रहा हूं और इस उदाहरण के लिए %rowtype का उपयोग कर रहा हूं।
आशा है कि यह मदद करता है