Asumiendo su formData
la estructura de la tabla es fija y conocida, solo puede usar una expresión de mayúsculas y minúsculas para traducir formOption.fName
al valor de la columna coincidente:
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
Luego puede hacer que su procedimiento abra un cursor de referencia para esa consulta, usando un valor de argumento para el valor de ID.
Si el formData
la estructura no se conoce, o no es estática, entonces probablemente tenga problemas mayores; pero para esto necesitaría recurrir a SQL dinámico. Como punto de partida, podría hacer algo como:
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;
/
Esto usa todas las columnas realmente definidas en la tabla para crear la expresión de caso en tiempo de ejecución; porque el caso de su fieldName
puede que no coincida con el diccionario de datos, estoy forzando todo a minúsculas para comparar. También estoy restringiendo las columnas de cadena para simplificar el caso, pero si necesita columnas que son otros tipos de datos, entonces cada when ... then
cláusula de las expresiones de caso necesitaría verificar el tipo de datos de esa columna (que puede agregar al r
cursor) y convierta el valor real de la columna en una cadena de forma adecuada. Todos los valores deben terminar en el mismo tipo de datos, por lo que en realidad deben ser cadenas.
De todos modos, probando esto desde 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.
Puede consultar fieldOptions
para obtener los posibles nombres de columna en su lugar, pero aún puede tener el problema de conversión de tipo de datos, que sería más difícil de manejar; pero si todos los formData
referenciados los campos son en realidad cadenas, entonces eso sería:
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;