あなたが得たエラーは正しいですが、 EXECUTE IMMEDIATEステートメントv_today
の範囲内の有効な識別子ではありません。代わりにバインド変数を使用する必要があります。
declare
v_TODAY number;
begin
select TODAY into v_TODAY from LOCATION;
execute immediate 'truncate table table_EOD';
execute immediate 'insert into table_EOD (key1, key2, ASOF, IDATE)
select key1, key2, ASOF, IDATE
from table
where ASOF = to_char(to_date(:1)-1)
and DATE between :1 and to_char(to_date(:1)+1)'
using v_today, v_today, v_today;
end;
/
さらに2点。まず、LOCATION に複数の行がある場合、機能しselect into ...
ません。これは、v_today
1 つの値しか保持できないためです。例外 TOO_MANY_ROWS が発生します。選択した行が多すぎます。
次に、2 番目の EXECUTE IMMEDIATE は必要ありません。参照しているオブジェクトがブロックのコンパイル前に存在しない場合、または SQL を動的に生成している場合にのみ、即時実行で DML を実行する必要があります。
truncate
これは DDL であるため、内部および EXECUTE IMMEDIATE ステートメントを実行する必要があります。これにより、次のことが残ります。
declare
v_TODAY number;
begin
select TODAY into v_TODAY from LOCATION; -- Still wrong!
execute immediate 'truncate table table_EOD';
insert into table_EOD (key1, key2, ASOF, IDATE)
select key1, key2, ASOF, IDATE
from table
where ASOF = to_char(to_date(v_TODAY)-1)
and DATE between v_TODAY and to_char(to_date(v_TODAY)+1);
end;
/
さて、あなたのコメントから、あなたが実際にランダムな日付ではなく今日を望んでおり、エラーの原因である LOCATIONの日付として数値を使用していることに気付きました。今日の日付にオラクルの [ ] を使用しないのはなぜですか?sysdate
declare
v_TODAY date := sysdate;
begin
execute immediate 'truncate table table_EOD';
insert into table_EOD (key1, key2, ASOF, IDATE)
select key1, key2, ASOF, IDATE
from table
where ASOF = trunc(sysdate) - 1
and DATE between trunc(v_TODAY) and trunc(v_TODAY) + 1;
end;
/
独自の日付を使用したい場合は、LOCATION に数字の代わりに日付を入れる方法を考え出す必要があります。