formData
を想定 テーブル構造は固定されており、既知です。case式を使用して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
次に、ID値の引数値を使用して、プロシージャでそのクエリの参照カーソルを開くことができます。
formData
の場合 構造が不明であるか、静的でない場合は、おそらくより大きな問題が発生します。ただし、このためには、動的SQLにフォールバックする必要があります。出発点として、次のようなことができます。
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;