您遇到的错误是正确的,它不是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;
/
还有两点。首先,如果您在 LOCATION 中有不止一行,那么您select into ...
将无法正常工作。这是因为v_today
只能保存一个值。将引发异常 TOO_MANY_ROWS;您将选择太多行!
其次,不需要第二个 EXECUTE IMMEDIATE。如果您引用的对象在编译块之前不存在,或者您正在动态生成 SQL,您只需在执行立即执行 DML。
您仍然需要执行truncate
内部和 EXECUTE IMMEDIATE 语句,因为这是 DDL。这将为您留下以下内容:
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 中使用数字作为日期,这是导致错误的原因。为什么不直接使用 Oracle 的 [ 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中放置日期而不是数字。