यह एक बहुत ही अजीबोगरीब आवश्यकता प्रतीत होती है, और जिसे एक मजबूत तरीके से हल करना मुश्किल होगा। STMT_OR_VALUE वन कॉलम टू यूसेज एंटी-पैटर्न का अवतार है। इसके अलावा, STMT_OR_VALUE को हल करने के लिए प्रवाह नियंत्रण तर्क और गतिशील SQL के उपयोग की आवश्यकता होती है। नतीजतन यह एक शुद्ध एसक्यूएल समाधान नहीं हो सकता है:गतिशील क्वेरी को इकट्ठा करने और निष्पादित करने के लिए आपको पीएल/एसक्यूएल का उपयोग करने की आवश्यकता है।
समाधान के लिए अवधारणा का प्रमाण यहां दिया गया है। मैंने एक फ़ंक्शन चुना है जिसे आप SQL से कॉल कर सकते हैं। यह एक धारणा पर निर्भर करता है:प्रत्येक क्वेरी स्ट्रिंग जिसे आप TEST1 में सम्मिलित करते हैं।STMT_OR_VALUE में एक अंकीय स्तंभ का प्रक्षेपण होता है और प्रत्येक मान स्ट्रिंग केवल संख्यात्मक डेटा का CSV है . इस प्रावधान के साथ एक फ़ंक्शन का निर्माण करना आसान है जो या तो एक गतिशील क्वेरी निष्पादित करता है या स्ट्रिंग को संख्याओं की एक श्रृंखला में टोकन करता है; दोनों को एक नेस्टेड तालिका में सामूहिक रूप से एकत्रित किया जाता है:
create or replace function get_ids (p_name in test1.name%type)
return sys.odcinumberlist
is
l_rec test1%rowtype;
return_value sys.odcinumberlist;
begin
select * into l_rec
from test1
where name = p_name;
if l_rec.type = 'SQL_QUERY' then
-- execute a query
execute immediate l_rec.stmt_or_value
bulk collect into return_value;
else
-- tokenize a string
select xmltab.tkn
bulk collect into return_value
from ( select l_rec.stmt_or_value from dual) t
, xmltable( 'for $text in ora:tokenize($in, ",") return $text'
passing stmt_or_value as "in"
columns tkn number path '.'
) xmltab;
end if;
return return_value;
end;
/
ध्यान दें कि डायनेमिक SQL स्टेटमेंट को निष्पादित करने के एक से अधिक तरीके हैं और CSV को संख्याओं की एक श्रृंखला में टोकन करने के कई तरीके हैं। मेरे निर्णय मनमाना हैं:बेझिझक अपने पसंदीदा तरीकों को यहां बदलें।
इस फ़ंक्शन को table()
. के साथ लागू किया जा सकता है कॉल करें:
select *
from data
where id in ( select * from table(get_ids('first'))) -- execute query
or id in ( select * from table(get_ids('second'))) -- get string of values
/
इस दृष्टिकोण का बड़ा लाभ यह है कि यह STMT_OR_VALUE के मूल्यांकन के आसपास के तर्क को समाहित करता है और गतिशील SQL के उपयोग को छुपाता है। नतीजतन, पठनीयता को बनाए रखते हुए, या आईडी का एक सेट बनाने के लिए और तंत्र जोड़ने के लिए इसे किसी भी SQL कथन में नियोजित करना आसान है।
हालांकि, यह समाधान भंगुर है। यह तभी काम करेगा जब test1
. के मान तालिका नियमों का पालन करें। यही है, न केवल उन्हें एकल संख्याओं की एक धारा में परिवर्तनीय होना चाहिए, बल्कि SQL कथन मान्य और निष्पादन योग्य तत्काल होना चाहिए। उदाहरण के लिए, प्रश्न के नमूना डेटा में पिछला सेमी-कोलन अमान्य है और तत्काल तत्काल प्रभाव डालेगा। डायनामिक एसक्यूएल कम से कम कठिन नहीं है क्योंकि यह संकलन त्रुटियों को रनटाइम त्रुटियों में परिवर्तित करता है।