2016-02-06 19 views
2

我有采用下列參數的PL/SQL程序/參數獲取ORA-01861 - 文字不匹配的SQLPlus格式字符串只有

Procedure create_test(mode_in in number, value1_in in number, 
     value2_in in number, value3_in in varchar2); 

我使用下面的PL/SQL塊調用和執行過程

DECLARE 
    lv_mode NUMBER; 
    lv_value1_in NUMBER; 
    lv_value2_in NUMBER; 
    lv_value3 VARCHAR2(3); 
BEGIN 
    lv_mode := 1; 
    lv_value1_in := 1; 
    lv_value2_in := 1; 
    lv_value3_in := 'ES'; 

    CREATE_TEST(
    mode_in => lv_mode , 
    value1_in => lv_value1_in, 
    value2_in => lv_value2_in, 
    value3_in => lv_value3_in 
); 
--rollback; 
END; 
/

如果我將上面的SQL塊粘貼到SQLDeveloper中並執行它,它將毫無問題地運行。 如果我把它放在一個文件並通過SQL執行它加上,我得到以下錯誤(如果直接在sqlplus運行它同樣的問題):

ORA-01861: literal does not match format string 

通常當我得到這個錯誤,這個問題通常是相關到日期。我不確定上面有什麼問題,因爲沒有涉及日期 - 尤其是考慮到相同的SQL塊在IDE中工作但不在SQLPLus中的事實。 SQLPlus處理文字是否與IDE略有不同?

我的猜測是SQLPlus中的一些參數處理它的方式不同 - 但是哪一個?

+0

存儲過程中的變量被稱爲'mode-in','value1_in','value2'和'value3'。通話中你名字錯了。 –

+0

對不起,是一個錯字糾正。 – ziggy

+0

很難說,看着'CREATE_TEST'程序的代碼。 – krokodilko

回答

3

滑稽的錯誤:TO_DATE(SYSDATE, 'DD-MON-YYYY HH:MI:SS')

只需更換與程序SYSDATE這種表達..


SYSDATE函數的返回數據類型是DATE
https://docs.oracle.com/cd/B19306_01/server.102/b14200/functions172.htm


TO_DATE本功能離子預計任CHARVARCHAR2NCHAR,或NVARCHAR2型,因爲它的第一個參數:
http://docs.oracle.com/cd/B19306_01/server.102/b14200/functions183.htm


該過程到達SYSDATE(類型DATE)作爲第一參數,其被預期爲字符串(VARCHAR ,CHAR等)。在這種情況下,Oracle會在內部使用TO_CHAR函數將DATE隱式轉換爲CHHAR/VARCHAR2。
可以說,上述表達式在內部轉換爲:

TO_DATE( TO_CHAR(sysdate) , 'DD-MON-YYYY HH:MI:SS') 

更多關於可以在這裏找到(滾動部分:「數據轉換 - 隱式和顯式數據轉換):imlicit轉換規則
https://docs.oracle.com/cd/B19306_01/server.102/b14200/sql_elements002.htm


從上述鏈接的一個基本片段:

Implici t轉換取決於其發生的上下文,並且在任何情況下可能都不會以相同的方式工作。例如,從日期時間值到VARCHAR2值的隱式轉換 可能會返回意外的 年,具體取決於NLS_DATE_FORMAT參數的值。


換言之 - TO_CHAR(some-date)沒有第二個參數(格式)使用從會議作出NLS_DATE_FOMRAT變量的值。

如果您在SQL-Developer上檢查此參數,它可能是:'DD-MON-YYYY HH:MI:SS'(在SQL-Developer中,此參數的值在選項中配置:Tools/Preferences/Database/NLS

但是,如果您在SQL-Plus中檢查NLS_DATE_FORMAT值,它將與'DD-MON-YYYY HH:MI:SS'不同.SQL-Plus根據您的環境的語言設置確定NLS設置的值(Windows ,Linux的等),並從NLS_LANG enironment varable(如果存在的話)

您可以在會話中使用更改此參數:
ALTER SESSION SET NLS_DATE_FORMAT = 'DD-MON-YYYY HH:MI:SS';
和(舊)程序將工作

1

您對「TO_DATE(SYSDATE,'DD-MON-YYYY HH:MI:SS')」的使用的使用存在根本上的缺陷。 to_date函數接受一個字符串作爲它的第一個參數,但是你傳遞了一個日期SYSDATE。這會強制oracle首先使用NLS_DATE_FORMAT的會話級別設置將SYSDATE隱式轉換爲字符串。獲得該字符串後,它將其轉換回DATE,並且必須假定派生字符串與您提供的'DD-MON-YYYY HH:MI:SS'格式匹配。它在SQL Dev中工作,因爲你已經配置它將NLS_DATE_FORAMT設置爲'DD-MON-YYYY HH:MI:SS',但這不是數據庫默認格式,所以它在sqlplus下失敗。您需要解決將日期(sysdate)傳遞給to_date函數的根本缺陷,而不是使用NLS設置。

相關問題