在底部回答,最终发现。 thx所有的贡献。
我必须创建一个脚本,我将在一个存储过程中生成,然后每隔几个月运行一次。它需要进入一些特定的表并删除旧记录。我认为这将非常简单,但我仍然遇到同样的问题。
如果我尝试运行我得到的代码和无效的标识符错误,它似乎是日期字段的问题,其中oracle默认使用字母数月,我尝试了各种日期格式化,但我似乎没有工作。
我声明要从哪个日期删除,然后将执行立即声明串起来,该声明将循环通过包含表名的tabletoclean表,以及我将执行清理的表的日期字段名称。 / p>
错误代码为ORA-00904:“APR”无效的意图 我猜它是因为它试图使用APR - APRIL而不是04.但我不知道。据我所知,没有一个dtl_fields使用月份名称日期格式化。
Declare
dtldate date := to_date(add_months( to_date(sysdate), -24 ), 'dd-mm-yy');
Begin
for tbl IN (Select * from tbltoclean)
loop
execute immediate 'Delete from '||tbl.tbl_name || ' where ' || tbl.dtl_field ||' < ' || dtldate;
DBMS_OUTPUT.PUT_LINE ('Deleted from '|| to_char(tbl.tbl_name));
end loop;
end;
如果我在dbms.output中运行execute immediate字符串,则返回字符串 从mytable中选择* datefield&lt; 30-APR-16
确认问题正确地与日期格式化有关。
编辑/答案 问题出在dtldate变量上。它将日期发布到执行立即,如下所示。
从mytable中选择* datefield&lt; 30-APR-16
这不起作用,但
从mytable中选择* datefield&lt; '30 -APR-16'
可以工作,所以我编辑了以下代码的字符串。
Declare
dtldate date := add_months( to_date(sysdate), -24 );
Begin
for tbl IN (Select * from tbltoclean)
loop
execute immediate 'Select null from '||tbl.tbl_name || ' where ' || tbl.dtl_field ||' < ' || 'to_date('''||dtldate||''')'; --dtldate have escaped ''
DBMS_OUTPUT.PUT_LINE ('Deleted from '|| to_char(tbl.tbl_name));
end loop;
end;
答案 0 :(得分:2)
SYSDATE
是一个返回DATE
数据类型的函数;
TO_DATE
)是没有用的。
所以,这可能会做你想要的:
declare
dtldate date := add_months(trunc(sysdate), -24);
begin
for tbl in (select * from tbltoclean)
loop
execute immediate 'Delete from '||tbl.tbl_name ||
' where ' || tbl.dtl_field ||' < DATE ''' || to_char(dtldate, 'YYYY-MM-DD') || '''';
dbms_output.put_line ('Deleted from '|| to_char(tbl.tbl_name));
end loop;
end;
答案 1 :(得分:-1)
这是处理日期的正确方法:
DECLARE
--
DTLDATE DATE;
--
BEGIN
--
DTLDATE := TRUNC(SYSDATE) -- 30/04/2018 14:36 -> 30/04/2018
--
DTLDATE := ADD_MONTHS(DTLDATE, -24) -- 30/04/2018 -> 30/04/2016
--
FOR TBL IN (SELECT * FROM TBLTOCLEAN) LOOP
--
EXECUTE IMMEDIATE 'DELETE FROM '||TBL.TBL_NAME ||
' WHERE ' || TBL.DTL_FIELD ||' < :DTLDATE'
USING DTLDATE;
DBMS_OUTPUT.PUT_LINE ('DELETED FROM '|| TBL.TBL_NAME);
--
END LOOP;
--
END;