[英]Possible Date assignment error ORA-01858: a non-numeric character was found where a numeric was expected
I'm getting the error ORA-01858: a non-numeric character was found where a numeric was expected, which I think is because the date assignment in my code isn't correct. 我收到错误ORA-01858:在非预期的数字位置发现了一个非数字字符,我认为这是因为代码中的日期分配不正确。 Can someone have a look at my code snippet below and let me known the correct way of assigning the date if it's wrong please? 有人可以看一下下面的代码片段,如果错误的话,可以让我知道分配日期的正确方法吗?
Declare
v_task_start DATE;
v_task_completion DATE;
v_prj_start DATE;
v_prj_completion DATE;
l_start_date DATE;
l_completion_date DATE;
v_task_id NUMBER;
v_prj_id NUMBER;
CURSOR c_tasks_to_update IS
SELECT
pt.TASK_ID,
pt.Project_id AS Task_Prj_Id,
pt.start_date AS Task_start,
pt.Completion_date AS Task_Completion,
ppa.start_date AS Project_start,
ppa.completion_date AS Project_completion
INTO
v_task_id, v_prj_id, v_task_start, v_task_completion, v_prj_start, v_prj_completion
FROM pa_tasks pt, pa_projects_all ppa
WHERE pt.project_id = ppa.project_id
AND pt.created_by = 1623
and to_date(pt.creation_date,'DD-MON-YY') = to_date('26-SEP-2014', 'DD-MON-YY');
BEGIN
FOR ctask_update in c_tasks_to_update
LOOP
v_task_start := ctask_update.Task_start;
v_task_completion := ctask_update.Task_Completion;
v_prj_start := ctask_update.Project_start;
v_prj_completion := ctask_update.Project_completion;
IF ((v_task_start <> v_prj_start) and (v_task_completion <> v_prj_completion))
THEN
DBMS_OUTPUT.put_line( 'Task Start date is not equal to Project start date,
Task completion date is not equal to Project completion date '
||v_task_start||' '||v_prj_start||' '||v_task_completion ||' '||
v_prj_completion);
l_start_date := to_date(trunc(v_prj_start),'DD_MON_YY');
/*SELECT START_DATE FROM PA_PROJECTS_ALL
INTO l_start_date
FROM pa_projects_all WHERE project_id = v_prj_id;*/
l_completion_date := to_date('trunc(v_prj_completion)','DD_MON_YY');
/*SELECT completion_date FROM PA_PROJECTS_ALL
INTO l_completion_date
FROM pa_projects_all WHERE project_id = v_prj_id;*/
DBMS_OUTPUT.put_line( 'Task start date to be updated to '||
to_char(l_start_date));
DBMS_OUTPUT.put_line( 'Task completion date to be updated to '||
to_char(l_completion_date));
End;
I don't get to see the output statements Task start date to be updated to:xxxx
. 我看不到输出语句“ Task start date to be updated to:xxxx
。 So the exception is occurring here. 因此,这里发生了异常。
There are a number of issues I can see here. 我在这里可以看到很多问题。 Firstly, the following line: 首先,以下行:
and to_date(pt.creation_date,'DD-MON-YY') = to_date('26-SEP-2014', 'DD-MON-YY');
What is the type of pt.creation_date
? pt.creation_date
是什么类型? CHAR
, VARCHAR2
or DATE
? CHAR
, VARCHAR2
或DATE
?
Don't use CHAR
or VARCHAR2
columns for dates as otherwise all sorts of other junk could end up in your date column: for example 31-SEP-14
, tomorrow
, n/a
, asdf
, all of which will cause problems later on during processing. 请勿将CHAR
或VARCHAR2
列用作日期,否则所有其他垃圾内容都可能会出现在您的日期列中:例如31-SEP-14
, tomorrow
, n/a
, asdf
,所有这些都会在以后的发布中引起问题处理。 Your error may be caused by dirty data in this column. 您的错误可能是由此列中的脏数据引起的。
If pt.creation_date
is a DATE
, there is no need to call to_date
on it, as that will force Oracle to convert the date to a string and then back to a date. 如果pt.creation_date
是DATE
,则无需在其上调用to_date
,因为这将迫使Oracle将日期转换为字符串然后再转换为日期。 This is unnecessary. 这是不必要的。
Also, to_date('26-SEP-2014', 'DD-MON-YY')
isn't entirely correct as you are using a four-digit year 2014
in your date string and a two-digit year YY
in your date format picture. 另外, to_date('26-SEP-2014', 'DD-MON-YY')
也不完全正确,因为您在日期字符串中使用四位数的年份2014
和在日期格式中使用两位数的年份YY
图片。 However, although this looks odd, Oracle doesn't seem to have a problem with it. 但是,尽管这看起来很奇怪,但是Oracle似乎没有问题。
The next problem is here: 下一个问题在这里:
l_start_date := to_date(trunc(v_prj_start),'DD_MON_YY');
v_prj_start
is already a DATE
, so there's no need to convert it to a date. v_prj_start
已经是DATE
,因此无需将其转换为日期。 You are doing an unnecessary conversion from date to string and back again. 您正在进行不必要的从日期到字符串然后再返回的转换。 It is probably sufficient to just write 仅仅写就足够了
l_start_date := trunc(v_prj_start);
Also I'm not sure why you are using underscores in your date format picture ( 'DD_MON_YY'
). 另外,我不确定您为什么在日期格式图片( 'DD_MON_YY'
)中使用下划线。
The next problem I see is this line: 我看到的下一个问题是这一行:
l_completion_date := to_date('trunc(v_prj_completion)','DD_MON_YY');
This could well be the line that is generating your error. 这很可能是产生错误的那一行。 In fact, it is guaranteed to fail with exactly the error message you report. 实际上,它会因您报告的错误消息而完全失败。 This is because the string 'trunc(v_prj_completion)'
isn't a valid date in the format you specified. 这是因为字符串'trunc(v_prj_completion)'
不是您指定格式的有效日期。 Oracle is expecting a number at the start of your date string and you have given it the letter t
instead. Oracle在日期字符串的开头希望有一个数字,而您给它指定了字母t
。 I imagine you intended to write the following line instead: 我想您打算改为编写以下行:
l_completion_date := to_date(trunc(v_prj_completion),'DD_MON_YY');
However, once again, don't use to_date
on a DATE
value, so 但是,再次,不要在DATE
值上使用to_date
,因此
l_completion_date := trunc(v_prj_completion);
may well be enough. 可能就足够了。
Further on down there are two lines similar to the following: 接下来的两行类似于以下内容:
DBMS_OUTPUT.put_line( 'Task start date to be updated to '||
to_char(l_start_date));
Always use to_char
with a date format picture, eg to_char(l_start_date, 'DD-MON-YY')
. 始终将to_char
与日期格式的图片一起使用,例如to_char(l_start_date, 'DD-MON-YY')
。
Finally, as a general point, use four-digit years ( YYYY
) instead of two-digit years where possible. 最后,一般来说,请使用四位数的年份( YYYY
),而不是两位数的年份。 A 2-digit year 14
will be interpreted as 2014, and 15
as 2015, but how much further can you go before 2-digit years start being interpreted as in the last century? 2位数字的年份14
将被解释为2014年,而15
位将被解释为2015年,但是在2位数字年份开始像上世纪一样被解释之前,您还能走多远? Perhaps 50
will be interpreted as 1950? 也许50
将被解释为1950?
Just a wild guess: 只是一个疯狂的猜测:
As I've noticed you use TO_DATE
in your query to convert pt.creation_date
to a proper date value, I could assume that maybe other date are stored as string in your table as well (which is a bad idea™ ). 正如我已经注意到的,您在查询中使用TO_DATE
将pt.creation_date
转换为适当的日期值,我可以假设其他日期也可能以字符串形式存储在表中(这是一个不好的主意 )。
So I would try something like that: 所以我会尝试这样的事情:
v_task_start := TO_DATE(ctask_update.Task_start,'DD-MON-YY');
v_task_completion := TO_DATE(ctask_update.Task_Completion,'DD-MON-YY');
v_prj_start := TO_DATE(ctask_update.Project_start,'DD-MON-YY');
v_prj_completion := TO_DATE(ctask_update.Project_completion,'DD-MON-YY');
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.