簡體   English   中英

可能的日期分配錯誤ORA-01858:在期望數字的位置找到了非數字字符

[英]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是什么類型? CHARVARCHAR2DATE

請勿將CHARVARCHAR2列用作日期,否則所有其他垃圾內容都可能會出現在您的日期列中:例如31-SEP-14tomorrown/aasdf ,所有這些都會在以后的發布中引起問題處理。 您的錯誤可能是由此列中的臟數據引起的。

如果pt.creation_dateDATE ,則無需在其上調用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_DATEpt.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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM