![](/img/trans.png)
[英]Error ORA-01858: a non-numeric character was found where a numeric was expected when running query
[英]Possible Date assignment error ORA-01858: a non-numeric character was found where a numeric was expected
我收到错误ORA-01858:在非预期的数字位置发现了一个非数字字符,我认为这是因为代码中的日期分配不正确。 有人可以看一下下面的代码片段,如果错误的话,可以让我知道分配日期的正确方法吗?
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;
我看不到输出语句“ Task start date to be updated to:xxxx
。 因此,这里发生了异常。
我在这里可以看到很多问题。 首先,以下行:
and to_date(pt.creation_date,'DD-MON-YY') = to_date('26-SEP-2014', 'DD-MON-YY');
pt.creation_date
是什么类型? CHAR
, VARCHAR2
或DATE
?
请勿将CHAR
或VARCHAR2
列用作日期,否则所有其他垃圾内容都可能会出现在您的日期列中:例如31-SEP-14
, tomorrow
, n/a
, asdf
,所有这些都会在以后的发布中引起问题处理。 您的错误可能是由此列中的脏数据引起的。
如果pt.creation_date
是DATE
,则无需在其上调用to_date
,因为这将迫使Oracle将日期转换为字符串然后再转换为日期。 这是不必要的。
另外, to_date('26-SEP-2014', 'DD-MON-YY')
也不完全正确,因为您在日期字符串中使用四位数的年份2014
和在日期格式中使用两位数的年份YY
图片。 但是,尽管这看起来很奇怪,但是Oracle似乎没有问题。
下一个问题在这里:
l_start_date := to_date(trunc(v_prj_start),'DD_MON_YY');
v_prj_start
已经是DATE
,因此无需将其转换为日期。 您正在进行不必要的从日期到字符串然后再返回的转换。 仅仅写就足够了
l_start_date := trunc(v_prj_start);
另外,我不确定您为什么在日期格式图片( 'DD_MON_YY'
)中使用下划线。
我看到的下一个问题是这一行:
l_completion_date := to_date('trunc(v_prj_completion)','DD_MON_YY');
这很可能是产生错误的那一行。 实际上,它会因您报告的错误消息而完全失败。 这是因为字符串'trunc(v_prj_completion)'
不是您指定格式的有效日期。 Oracle在日期字符串的开头希望有一个数字,而您给它指定了字母t
。 我想您打算改为编写以下行:
l_completion_date := to_date(trunc(v_prj_completion),'DD_MON_YY');
但是,再次,不要在DATE
值上使用to_date
,因此
l_completion_date := trunc(v_prj_completion);
可能就足够了。
接下来的两行类似于以下内容:
DBMS_OUTPUT.put_line( 'Task start date to be updated to '||
to_char(l_start_date));
始终将to_char
与日期格式的图片一起使用,例如to_char(l_start_date, 'DD-MON-YY')
。
最后,一般来说,请使用四位数的年份( YYYY
),而不是两位数的年份。 2位数字的年份14
将被解释为2014年,而15
位将被解释为2015年,但是在2位数字年份开始像上世纪一样被解释之前,您还能走多远? 也许50
将被解释为1950?
只是一个疯狂的猜测:
正如我已经注意到的,您在查询中使用TO_DATE
将pt.creation_date
转换为适当的日期值,我可以假设其他日期也可能以字符串形式存储在表中(这是一个不好的主意 )。
所以我会尝试这样的事情:
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.