问题
I have a PL/SQL procedure that takes the following arguments/parameters
Procedure create_test(mode_in in number, value1_in in number,
value2_in in number, value3_in in varchar2);
I am using the following pl/sql block to call and execute the procedure
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;
/
If i paste the above sql block into SQLDeveloper and execute it, it runs with no problems. If i put it in a file and execute it through SQL plus, i get the following error (same problem if run it directly in SQLPLus):
ORA-01861: literal does not match format string
Usually when i get this error, the issue is usually related to Dates. I am not sure what is wrong with the above as there are no dates involved - Especially given the fact that the same SQL block works in an IDE but not SQLPLus. Is SQLPlus handling the literals slightly differently than the IDE?
My guess is that some parameter in SQLPlus is handling it differently - but which one?
回答1:
Funny mistake: TO_DATE(SYSDATE, 'DD-MON-YYYY HH:MI:SS')
Just replace this expression with SYSDATE in the procedure..
The returned datatype of SYSDATE
function is DATE
:
https://docs.oracle.com/cd/B19306_01/server.102/b14200/functions172.htm
TO_DATE
function expects either CHAR
, VARCHAR2
, NCHAR
, or NVARCHAR2
type as it's first parameter:
http://docs.oracle.com/cd/B19306_01/server.102/b14200/functions183.htm
The procedure passes SYSDATE (of type DATE) as a first parameter, which is expected to be a string (VARCHAR, CHAR etc.). In this case Oracle performs an implicit conversion of DATE to CHHAR/VARCHAR2, using TO_CHAR function internally.
One can say that the above expression is converted internally to:
TO_DATE( TO_CHAR( sysdate ) , 'DD-MON-YYYY HH:MI:SS' )
More on imlicit conversion rules can be found here (scroll to section: "Data Conversion - Implicit and Explicit Data Conversion):
https://docs.oracle.com/cd/B19306_01/server.102/b14200/sql_elements002.htm
An essential fragment from the above link:
Implicit conversion depends on the context in which it occurs and may not work the same way in every case. For example, implicit conversion from a datetime value to a VARCHAR2 value may return an unexpected year depending on the value of the NLS_DATE_FORMAT parameter.
In other words - TO_CHAR( some-date )
without a second parameter (format) uses a value of NLS_DATE_FOMRAT variable taken from the session.
If you check this parameter on SQL-Developer, it will be probably: 'DD-MON-YYYY HH:MI:SS' (in SQL-Developer a value of this parameter is configured in option: Tools/Preferences/Database/NLS
But if you check NLS_DATE_FORMAT value in SQL-Plus, it will differ from 'DD-MON-YYYY HH:MI:SS'. SQL-Plus determines a value of NLS setting from language settings of your environment (Windows, Linux etc.) and from NLS_LANG enironment varable (if present).
You can change this parameter in your session using: ALTER SESSION SET NLS_DATE_FORMAT = 'DD-MON-YYYY HH:MI:SS';
and the (old) procedure will work.
回答2:
Your use of the statement " TO_DATE(SYSDATE, 'DD-MON-YYYY HH:MI:SS')" is fundamentally flawed. The to_date function takes a character string as its first arguement, but you are passing SYSDATE, which is a date. This forces oracle to first do an implicit conversion of SYSDATE to a character string, using the session level setting of NLS_DATE_FORMAT. Having gotten that character string, it then converts it back to a DATE, and has to assume that the derived character string matches your supplied format of 'DD-MON-YYYY HH:MI:SS'. It works in SQL Dev because you have it configured to set NLS_DATE_FORAMT to 'DD-MON-YYYY HH:MI:SS', but this is not the database default format, so it fails under sqlplus. Rather than monkey around with the NLS settings, you need to address the fundamental flaw up passing a date (sysdate) to the to_date function.
来源:https://stackoverflow.com/questions/35241870/getting-ora-01861-literal-does-not-match-format-string-on-sqlplus-only