Förutsatt din formData
tabellstrukturen är fixerad och känd, du kan bara använda ett kasusuttryck för att översätta formOption.fName
till det matchande kolumnvärdet:
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
Du kan sedan låta din procedur öppna en ref-markör för den frågan med ett argumentvärde för ID-värdet.
Om formData
struktur är inte känd, eller är inte statisk, då har du förmodligen större problem; men för detta måste du falla tillbaka till dynamisk SQL. Som utgångspunkt kan du göra något som:
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;
/
Detta använder alla kolumner som faktiskt definieras i tabellen för att skapa falluttrycket vid körning; eftersom fallet med ditt fieldName
kanske inte matchar dataordboken, jag tvingar allt att ge små bokstäver för jämförelse. Jag begränsar mig också till strängkolumner för att göra fallet enklare, men om du behöver kolumner som är andra datatyper så är var och en when ... then
satsen i kasusuttrycken skulle behöva kontrollera kolumnens datatyp (som du kan lägga till i r
markören) och konvertera det faktiska kolumnvärdet till en sträng på lämpligt sätt. Alla värden måste hamna i samma datatyp, så det måste verkligen vara strängar.
Hur som helst, testar detta från 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.
Du kan fråga fieldOptions
för att få de möjliga kolumnnamnen istället, men du kan fortfarande ha problem med datatypskonvertering, vilket skulle vara svårare att hantera; men om alla refererade formData
fält är faktiskt strängar då det skulle vara:
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;