我有以下代码未正确执行。我有数据存储在date_tmp(varchar)中,包括日期和非日期。我想将该列中的日期移动到date_run(日期),而不是日期的数据将移动到comments(varchar)列。当我运行以下代码时,整个数据集将移动到注释。当我编辑insert语句并运行dbms_outputline行时,它运行正常。我可能做错了什么?
DECLARE
CURSOR getrow IS
SELECT a.id, a.date_tmp
FROM mycolumn a
WHERE a.id < 1300;
v_date date;
BEGIN
FOR i in getrow LOOP
BEGIN
v_date := to_date(i.date_tmp, 'mm/dd/yy');
INSERT INTO mycolumn a(a.date_run)
VALUES(i.date_tmp);
EXCEPTION
WHEN OTHERS THEN
--dbms_output.put_line(i.date_tmp);
update mycolumn a
SET a.comments = i.date_tmp
where a.id = i.id;
END;
END LOOP;
END;
答案 0 :(得分:2)
您尝试将varchar i.date_tmp
插入日期字段。而是插入v_date
。
...
INSERT INTO mycolumn a (a.date_run)
VALUES(v_date);
...
但实际上你的要求是一个举动。这要求实际更新。所以我认为你真正想做的是:
...
update mycolumn a
SET a.date_run = v_date
where a.id = i.id
...
实际上,您可以使用一个函数来检查您是否有有效日期,然后您可以使用简单的更新语句来处理整个任务。
create or replace function is_a_date(i_date varchar2, i_pattern varchar2)
return date
is
begin
return to_date(i_date, i_pattern);
exception
when others return null;
end is_a_date;
使用该功能,您可以编写两个更新语句
update mycolumn
set date_run = to_date(date_tmp,'dd/mm/yy')
where is_a_date(date_tmp, 'dd/mm/yy') is not null;
update mycolumn
set comment = date_tmp
where is_a_date(date_tmp, 'dd/mm/yy') is null;
我设计了这个函数,你可以用各种方式使用它,因为它返回一个日期或null但是如果varchar不符合日期模式则没有例外。
答案 1 :(得分:1)
您有一个insert
,看起来您需要一个update
,就像您在异常处理程序中一样。所以只需将其更改为:
v_date := to_date(i.date_tmp, 'mm/dd/yy');
update mycolumn
set date_run = v_date
where id = i.id;
或者您可以缩短为:
update mycolumn
set date_run = to_date(i.date_tmp, 'mm/dd/yy')
where id = i.id;
答案 2 :(得分:1)
update mycolumn
set date_run = to_date(date_tmp,'dd/mm/yy')
where substr(date_tmp,1,2) between '1' and '31'
and substr(date_tmp,4,2) between '1' and '12'
and substr(date_tmp,7,2) between '00' and '99';
如果你的查询需要更快的速度,或者你在date_tmp中有大量的数据,因为函数is_a_date是确定的(总是返回相同的值,给定相同的X,Y值),你可以创建一个索引它:
create index mycol_idx on mycolumn(is_a_date(date_tmp));
当您使用该函数时,Oracle将使用您的索引,就像那些选择:
SELECT a.id, a.date_tmp
FROM mycolumn a
WHERE a.id < 1300
and is_a_date(a.date_tmp) is not null;
SELECT a.id, a.date_tmp
FROM mycolumn a
WHERE a.id < 1300
and (is_a_date(a.date_tmp) is not null and is_a_date(a.date_tmp)>sysdate-5);