あなたemp_rec
変数は、ローカルのPL/SQLレコードであると宣言しなければなりません。あなたも、静的なフィールド名を参照して、これを行うと:
execute immediate 'begin :x := emp_rec.emp_no; end;'
の動的SQLは、それを呼び出すブロックとは別のコンテキストで実行されます。そのコンテキスト内で新しい無名PL/SQLブロックを実行します。
外部の匿名ブロックの変数(ここではemp_rec
)は、動的SQLコンテキストの有効範囲外です。値を:x
に割り当てようとしているコードには存在しません。
あなたはおそらくこれを動的にするdbms_sql
で何かを行うことができますが、あなたがテーブルの列を知っていればそれを行うのは容易になるだろう:
declare
l_data varchar2(4000); -- long is deprecated; how big does this really need to be?
emp_rec EMP%rowtype;
begin
select * INTO emp_rec from EMP A WHERE A.EMP_NO = '001322';
for x in (
select column_name, data_type
from user_tab_columns
where table_name = 'EMP'
)
loop
case x.column_name
when 'EMP_NO' then
l_data := emp_rec.emp_no;
-- when clauses for each column in your real table
when 'FIRST_NAME' then
l_data := emp_rec.first_name;
when 'LAST_NAME' then
l_data := emp_rec.last_name;
-- list other columns and assignments
-- else ...
end case;
dbms_output.put_line(x.column_name || ' = ' || l_data);
end loop;
end;
/
@APCが指摘したように、ループは今少しではあるが無意味な、あなただけ行うことができますので、:
declare
emp_rec EMP%rowtype;
begin
select * INTO emp_rec from EMP A WHERE A.EMP_NO = '001322';
dbms_output.put_line('EMP_NO = ' || emp_rec.emp_no);
dbms_output.put_line('FIRST_NAME = ' || emp_rec.first_anme);
dbms_output.put_line('LAST_NAME = ' || emp_rec.last_name);
-- ... any other columns you want to show
end;
/
ループボディの列名をハードコードする場合は、USER_TAB_COLUMNSを照会する価値はほとんどありませんすべて – APC