![](/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.