मान लें कि आपका formData
तालिका संरचना निश्चित और ज्ञात है, आप formOption.fName
का अनुवाद करने के लिए बस केस एक्सप्रेशन का उपयोग कर सकते हैं मेल खाने वाले कॉलम मान के लिए:
select fo.fieldLabel as label,
case fo.fieldName
when 'fName' then fd.fName
when 'lName' then fd.lName
when 'nName' then fd.mName
end as value
from formData fd
join fieldOptions fo
on fo.formType = fd.formtype
where fd.id = 3;
LABEL VALUE
-------------------- --------------------
First Frank
Surname Peterson
Middle Initial
...
where fd.id = 3;
LABEL VALUE
-------------------- --------------------
First Name Bob
Last Name Smith
Middle
फिर आप आईडी मान के लिए तर्क मान का उपयोग करके अपनी प्रक्रिया को उस क्वेरी के लिए रेफ कर्सर खोल सकते हैं।
अगर formData
संरचना ज्ञात नहीं है, या स्थिर नहीं है, तो आपको शायद बड़ी समस्याएं हैं; लेकिन इसके लिए आपको डायनामिक एसक्यूएल पर वापस आना होगा। आरंभिक बिंदु के रूप में, आप कुछ ऐसा कर सकते हैं:
create procedure p42 (p_id number, p_refcursor out sys_refcursor) as
l_stmt varchar2(32767);
begin
l_stmt := 'select fo.fieldLabel as label, case lower(fo.fieldName) ';
for r in (
select column_name from user_tab_columns
where table_name = 'FORMDATA'
and data_type = 'VARCHAR2'
)
loop
l_stmt := l_stmt || ' when ''' || lower(r.column_name) || ''' then fd.' || r.column_name;
end loop;
l_stmt := l_stmt || ' end as value '
|| 'from formData fd '
|| 'join fieldOptions fo '
|| 'on fo.formType = fd.formtype '
|| 'where fd.id = :d1';
open p_refcursor for l_stmt using p_id;
end p42;
/
यह रन टाइम पर केस एक्सप्रेशन बनाने के लिए वास्तव में तालिका में परिभाषित सभी कॉलम का उपयोग करता है; क्योंकि आपके fieldName
. का मामला डेटा डिक्शनरी से मेल नहीं खा सकता है, मैं तुलना के लिए सब कुछ कम करने के लिए मजबूर कर रहा हूं। मैं मामले को सरल बनाने के लिए स्ट्रिंग कॉलम तक भी सीमित कर रहा हूं, लेकिन यदि आपको कॉलम की आवश्यकता है जो अन्य डेटा प्रकार हैं तो प्रत्येक when ... then
केस एक्सप्रेशन के क्लॉज को उस कॉलम के डेटा प्रकार की जांच करनी होगी (जिसे आप r
में जोड़ सकते हैं) कर्सर) और वास्तविक कॉलम मान को उचित रूप से एक स्ट्रिंग में कनवर्ट करें। सभी मानों को एक ही डेटा प्रकार को समाप्त करना होता है, इसलिए इसे वास्तव में तार होना चाहिए।
वैसे भी, SQL*Plus से इसका परीक्षण करना:
var rc refcursor
exec p42(1, :rc);
PL/SQL procedure successfully completed.
print rc
LABEL VALUE
-------------------- --------------------
First Name Bob
Last Name Smith
Middle
3 rows selected.
आप fieldOptions
के बारे में पूछ सकते हैं इसके बजाय संभावित कॉलम नाम प्राप्त करने के लिए, लेकिन आपके पास अभी भी डेटा प्रकार रूपांतरण समस्या हो सकती है, जिससे निपटना कठिन होगा; लेकिन अगर सभी संदर्भित formData
फ़ील्ड वास्तव में तार हैं तो वह होगा:
for r in (
select fo.fieldName
from formData fd
join fieldOptions fo
on fo.formType = fd.formtype
where fd.id = p_id
)
loop
l_stmt := l_stmt || ' when ''' || r.fieldName || ''' then fd.' || r.fieldName;
end loop;